2D Game Development - sy2.Python-pygame

Python's pygame game development Use pygame m...
Python's pygame game development

Use pygame module in python to develop 2D games.

Pygame is a cross-platform Python module designed for electronic games.Contains images, sounds.Created on the basis of SDL, allows the development of real-time video games without being tied down by low-level languages such as C or lower-level assembly languages.Based on this assumption, all required game functions and concepts completely simplify the bitwise game logic itself, and all resource structures can be provided by advanced languages such as Python.

This experiment is a validation assignment with the code given by the teacher.
Development Scenario: Python 3.7.4 + Pygame1.9.6
Development Tools: PyCharm 2019.3.3 x64

Basics

Install pygame and type in cmd instructions based on python

pip install pygame


The picture above is because I have already installed it, prompting me that I have already installed it.If the network is not good, it is recommended to go to the official or mirror site to download the package, and then cd to the folder where the package is located, enter:

pip install pygame-1.9.6-cp37-cp37m-win_amd64.whl #Version by itself

Verify that python is installed and enter it in cmd

python

pygame window making

Set the window size and name as follows:

import pygame from pygame.locals import * import sys def hellow_world(): pygame.init() pygame.display.set_mode((640, 480)) pygame.display.set_caption("hellow world!") while True: for event in pygame.event.get(): if event.type==QUIT: pygame.quit() sys.exit() pygame.display.update() if __name__ == "__main__": hellow_world()

Execution results:

Tank Battle

Use the keyboard to move tanks and pygame to develop games.
The code is as follows:

import os, sys, pygame from pygame.locals import * # Control tank movement def control_tank(event): speed = [x, y] = [0, 0] speed_offset = 1 if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: speed[0] -= speed_offset if event.key == pygame.K_RIGHT: speed[0] = speed_offset if event.key == pygame.K_UP: speed[1] -= speed_offset if event.key == pygame.K_DOWN: speed[1] = speed_offset if event.type == pygame.KEYUP: if event.type in [pygame.K_UP, pygame.K_DOWN, pygame.K_RIGHT, pygame.K_LEFT]: speed = [0, 0] return speed # Set parameters to start the game def play_tank(): pygame.init() window_size = Rect(0, 0, 700, 650) speed = [1, 1] color_white = (255, 255, 255) screen = pygame.display.set_mode(window_size.size) pygame.display.set_caption('Tank Battle') tank_image = pygame.image.load('images\\tankD.bmp') back_image = pygame.image.load('images\\back_image.jpg') tank_rect = tank_image.get_rect() while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() cur_speed = control_tank(event) tank_rect = tank_rect.move(cur_speed).clamp(window_size) screen.blit(back_image, (0, 0)) screen.blit(tank_image, tank_rect) pygame.display.update() if __name__ == '__main__': play_tank()

Execution results:

Source material:

ccsprite

In game development, objects that display images are often referred to as Sprite elves.A fairy is a graphic that has size, color, pattern, can be moved, and can interact with other graphic objects.
Tank elves (code):

import pygame, sys pygame.init() class Tank(pygame.sprite.Sprite): def __init__(self, filename, initial_position): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load(filename) self.rect = self.image.get_rect() self.rect.bottomright = initial_position screen = pygame.display.set_mode((640, 480)) screen.fill([255, 255, 255]) fi = 'images/tankD.bmp' b = Tank(fi, [150, 100]) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() screen.blit(b.image, b.rect) pygame.display.update()

Execution results:

Wizard test (code):

import pygame from pygame.locals import * class MySprite(pygame.sprite.Sprite): def __init__(self, target): pygame.sprite.Sprite.__init__(self) self.target_surface = target self.image = None self.master_image = None self.rect = None self.topleft = 0, 0 self.frame = 0 self.old_frame = -1 self.frame_width = 1 self.frame_height = 1 self.first_frame = 0 self.last_frame = 0 self.columns = 1 self.last_time = 0 def load(self,filename,width,height,columns): self.master_image = pygame.image.load(filename).convert_alpha() self.frame_width = width self.frame_height = height self.rect = 0, 0, width, height self.columns = columns rect = self.master_image.get_rect() self.last_frame = (rect.width // width) * (rect.height // height) - 1 def update(self, current_time, rate=60): if current_time > self.last_time + rate: self.frame += 1 if self.frame > self.last_frame: self.frame = self.first_frame self.last_time = current_time if self.frame != self.old_frame: frame_x = (self.frame % self.columns) * self.frame_width frame_y = (self.frame // self.columns) * self.frame_height rect = (frame_x, frame_y, self.frame_width, self.frame_height) self.image = self.master_image.subsurface(rect) self.old_frame = self.frame pygame.init() screen = pygame.display.set_mode((800, 600), 0, 32) pygame.display.set_caption("Elf Test") font = pygame.font.Font(None, 18) framerate = pygame.time.Clock() cat = MySprite(screen) cat.load("images\\sprite2.png", 92, 95, 4) group = pygame.sprite.Group() group.add(cat) while True: framerate.tick(10) ticks = pygame.time.get_ticks() for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() key = pygame.key.get_pressed() if key[pygame.K_ESCAPE]: exit() screen.fill((0, 0, 255)) cat.update(ticks) screen.blit(cat.image, cat.rect) pygame.display.update()

Execution results:

Source material:

Retro Snaker

Keyboard keys are used to control the movement of the snake to eat food. When the party snake touches the outside wall, the game ends.
The code is as follows:

import pygame, sys, time, random from pygame.locals import * pygame.init() fpsClock = pygame.time.Clock() playSurface = pygame.display.set_mode((640, 480)) pygame.display.set_caption('snakey') # Define some colors redColor = pygame.Color(255, 0, 0) blackColor = pygame.Color(0, 0, 0) whiteColor = pygame.Color(255, 255, 255) greyColor = pygame.Color(150, 150, 150) # Initialized variables used in some programs snakePosition = [100, 100] snakeSegments = [[100, 100], [80, 100], [60, 100]] raspberryPosition = [300, 300] # Raspberry position raspberrySpawned = 1 # Whether or not to eat raspberries, 1 is not eaten, 0 is eaten direction = 'right' changeDirection = direction def gameOver(): gameOverFont = pygame.font.Font('images\\simfang.ttf', 72) gameOverSurf = gameOverFont.render('Game Over', True, greyColor) gameOverRect = gameOverSurf.get_rect() gameOverRect.midtop = (320, 10) playSurface.blit(gameOverSurf, gameOverRect) pygame.display.flip() time.sleep(5) pygame.quit() sys.exit() while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == KEYDOWN: if event.key == K_RIGHT or event.key == ord('d'): changeDirection = 'right' if event.key == K_LEFT or event.key == ord('a'): changeDirection = 'left' if event.key == K_UP or event.key == ord('w'): changeDirection = 'up' if event.key == K_DOWN or event.key == ord('s'): changeDirection = 'down' if event.key == K_ESCAPE: pygame.event.post(pygame.event.Event(QUIT)) if changeDirection == 'right' and not direction == 'left': direction = changeDirection if changeDirection == 'left' and not direction == 'right': direction = changeDirection if changeDirection == 'up' and not direction == 'down': direction = changeDirection if changeDirection == 'down' and not direction == 'up': direction = changeDirection if direction == 'right': snakePosition[0] += 20 if direction == 'left': snakePosition[0] -= 20 if direction == 'up': snakePosition[1] -= 20 if direction == 'down': snakePosition[1] += 20 # Add a section to the snake's body while placing it on the head snakeSegments.insert(0, list(snakePosition)) # Check that the X and Y coordinates of the snake head are equal to the coordinates of the raspberry (the player's target point) if snakePosition[0] == raspberryPosition[0] and snakePosition[1] == raspberryPosition[1]: raspberrySpawned = 0 else: snakeSegments.pop() # Add a new raspberry to the game interface: if raspberrySpawned == 0: x = random.randrange(1, 32) y = random.randrange(1, 24) raspberryPosition = [int(x*20), int(y*20)] raspberrySpawned = 1 playSurface.fill(blackColor) for position in snakeSegments: pygame.draw.rect(playSurface, whiteColor, Rect(position[0], position[1], 20, 20)) pygame.draw.rect(playSurface, redColor, Rect(raspberryPosition[0], raspberryPosition[1], 20, 20)) pygame.display.flip() if snakePosition[0] > 620 or snakePosition[0] < 0: gameOver() if snakePosition[1] > 460 or snakePosition[1] < 0: gameOver() for snakeBody in snakeSegments[1:]: if snakePosition[0] == snakeBody[0] and snakePosition[1] == snakeBody[1]: gameOver() fpsClock.tick(10)

Execution results:

Airplane Battle

The game starts, the music sounds, airplanes appear from above and move down. The player's task is to shoot bullets to destroy the enemy. For each enemy destroyed, the player accumulates 10 points.The game ends when the enemy is not destroyed by the player before it lands.
The code is as follows:

import pygame from sys import exit from pygame.locals import * import random # Define Classes SCREEN_WIDTH = 480 SCREEN_HEIGHT = 800 TYPE_SMALL = 1 TYPE_MIDDLE = 2 TYPE_BIG = 3 # ZiDan class Bullet(pygame.sprite.Sprite): def __init__(self, bullet_img, init_pos): pygame.sprite.Sprite.__init__(self) self.image = bullet_img self.rect = self.image.get_rect() self.rect.midbottom = init_pos self.speed = 10 def move(self): self.rect.top -= self.speed # Player class class Player(pygame.sprite.Sprite): def __init__(self, plane_img, player_rect, init_pos): pygame.sprite.Sprite.__init__(self) self.image = [] # List to store player plane pictures for i in range(len(player_rect)): self.image.append(plane_img.subsurface(player_rect[i]).convert_alpha()) self.rect = player_rect[0] # Initialize the rectangle where the picture is located self.rect.topleft = init_pos # Initialize the upper left corner coordinates of the rectangle self.speed = 8 # Initialize player airplane speed, here is a fixed value self.bullets = pygame.sprite.Group() # The collection of bullets fired by a player's aircraft self.img_index = 0 # Player Wizard Picture Index self.is_hit = False # Is the player hit # Launch Bullet def shoot(self, bullet_img): bullet = Bullet(bullet_img, self.rect.midtop) self.bullets.add(bullet) # Move up, you need to judge the boundary def moveUp(self): if self.rect.top <= 0: self.rect.top = 0 else: self.rect.top -= self.speed # Move down, you need to determine the boundary def moveDown(self): if self.rect.top >= SCREEN_HEIGHT - self.rect.height: self.rect.top = SCREEN_HEIGHT - self.rect.height else: self.rect.top += self.speed # Move left, you need to determine the boundary def moveLeft(self): if self.rect.left <= 0: self.rect.left = 0 else: self.rect.left -= self.speed # Move right, you need to determine the boundary def moveRight(self): if self.rect.left >= SCREEN_WIDTH - self.rect.width: self.rect.left = SCREEN_WIDTH - self.rect.width else: self.rect.left += self.speed # Enemy class class Enemy(pygame.sprite.Sprite): def __init__(self, enemy_img, enemy_down_imgs, init_pos): pygame.sprite.Sprite.__init__(self) self.image = enemy_img self.rect = self.image.get_rect() self.rect.topleft = init_pos self.down_imgs = enemy_down_imgs self.speed = 2 self.down_index = 0 def move(self): self.rect.top += self.speed # Initialize the game pygame.init() screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption('Airplane Battle') # Load Game Music bullet_sound = pygame.mixer.Sound('images/resources/sound/bullet.wav') enemy1_down_sound = pygame.mixer.Sound('images/resources/sound/enemy1_down.wav') game_over_sound = pygame.mixer.Sound('images/resources/sound/game_over.wav') bullet_sound.set_volume(0.3) enemy1_down_sound.set_volume(0.3) game_over_sound.set_volume(0.3) pygame.mixer.music.load('images/resources/sound/game_music.wav') pygame.mixer.music.play(-1, 0.0) pygame.mixer.music.set_volume(0.25) # Load Background Map background = pygame.image.load('images/resources/image/background.png').convert() game_over = pygame.image.load('images/resources/image/gameover.png') filename = 'images/resources/image/shoot.png' # It can also be loaded like this, with the same meaning as the previous sentence plane_img = pygame.image.load(filename) # Set player-related parameters player_rect = [] player_rect.append(pygame.Rect(0, 99, 102, 126)) # Player elf picture area player_rect.append(pygame.Rect(165, 360, 102, 126)) player_rect.append(pygame.Rect(165, 234, 102, 126)) # Player Explosion Elf Picture Area player_rect.append(pygame.Rect(330, 624, 102, 126)) player_rect.append(pygame.Rect(330, 498, 102, 126)) player_rect.append(pygame.Rect(432, 624, 102, 126)) player_pos = [200, 600] player = Player(plane_img, player_rect, player_pos) # Define surface-related parameters used by bullet objects bullet_rect = pygame.Rect(1004, 987, 9, 21) bullet_img = plane_img.subsurface(bullet_rect) # Define surface-related parameters used by enemy aircraft objects enemy1_rect = pygame.Rect(534, 612, 57, 43) enemy1_img = plane_img.subsurface(enemy1_rect) enemy1_down_imgs = [] enemy1_down_imgs.append(plane_img.subsurface(pygame.Rect(267, 347, 57, 43))) enemy1_down_imgs.append(plane_img.subsurface(pygame.Rect(873, 697, 57, 43))) enemy1_down_imgs.append(plane_img.subsurface(pygame.Rect(267, 296, 57, 43))) enemy1_down_imgs.append(plane_img.subsurface(pygame.Rect(930, 697, 57, 43))) enemies1 = pygame.sprite.Group() # Store destroyed planes to render destroyed elf animations enemies_down = pygame.sprite.Group() shoot_frequency = 0 enemy_frequency = 0 player_down_index = 16 score = 0 clock = pygame.time.Clock() running = True while running: # Control Game Maximum Frame Rate 60 clock.tick(60) # Controls the frequency at which bullets are fired and fires them if not player.is_hit: if shoot_frequency % 15 == 0: bullet_sound.play() player.shoot(bullet_img) shoot_frequency += 1 if shoot_frequency >= 15: shoot_frequency = 0 # Generate enemy aircraft if enemy_frequency % 50 == 0: enemy1_pos = [random.randint(0, SCREEN_WIDTH - enemy1_rect.width), 0] enemy1 = Enemy(enemy1_img, enemy1_down_imgs, enemy1_pos) enemies1.add(enemy1) enemy_frequency += 1 if enemy_frequency >= 100: enemy_frequency = 0 # Move bullets, delete if out of window for bullet in player.bullets: bullet.move() if bullet.rect.bottom < 0: player.bullets.remove(bullet) # Move enemy aircraft, delete if out of window for enemy in enemies1: # Move enemy aircraft enemy.move() # Determine if a player is hit if pygame.sprite.collide_circle(enemy, player): enemies_down.add(enemy) enemies1.remove(enemy) player.is_hit = True game_over_sound.play() break # Remove enemies after moving out of the screen if enemy.rect.top > SCREEN_HEIGHT: enemies1.remove(enemy) # Add the hit enemy plane object to the destroy enemy plane Group to render the destroy animation enemies1_down = pygame.sprite.groupcollide(enemies1, player.bullets, 1, 1) for enemy_down in enemies1_down: enemies_down.add(enemy_down) # Draw Background screen.fill(0) screen.blit(background, (0, 0)) # Draw player planes if not player.is_hit: screen.blit(player.image[player.img_index], player.rect) # Draw a normal plane # Change the picture index to animate the plane player.img_index = shoot_frequency // 8 else: # Effect handling after a player's plane is hit player.img_index = player_down_index // 8 screen.blit(player.image[player.img_index], player.rect) # Draw the exploding plane player_down_index += 1 if player_down_index > 47: running = False # Draw destroy animation for enemy_down in enemies_down: if enemy_down.down_index == 0: enemy1_down_sound.play() if enemy_down.down_index > 7: enemies_down.remove(enemy_down) score += 10 continue screen.blit(enemy_down.down_imgs[enemy_down.down_index // 2], enemy_down.rect) #Draw an exploding enemy plane enemy_down.down_index += 1 # Draw bullets and enemy aircraft player.bullets.draw(screen) enemies1.draw(screen) # Draw Score score_font = pygame.font.Font(None, 36) score_text = score_font.render('score: '+str(score), True, (128, 128, 128)) text_rect = score_text.get_rect() text_rect.topleft = [10, 10] screen.blit(score_text, text_rect) # Update Screen pygame.display.update() # Handle Game Exit for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() # Listen for keyboard events key_pressed = pygame.key.get_pressed() # Invalid if the player is hit if not player.is_hit: if key_pressed[K_w] or key_pressed[K_UP]: player.moveUp() if key_pressed[K_s] or key_pressed[K_DOWN]: player.moveDown() if key_pressed[K_a] or key_pressed[K_LEFT]: player.moveLeft() if key_pressed[K_d] or key_pressed[K_RIGHT]: player.moveRight() # Show final score after GameOver font = pygame.font.Font(None, 64) text = font.render('Final Score: '+str(score), True, (255, 0, 0)) text_rect = text.get_rect() text_rect.centerx = screen.get_rect().centerx text_rect.centery = screen.get_rect().centery + 24 screen.blit(game_over, (0, 0)) screen.blit(text, text_rect) # Show score and handle game exit while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() pygame.display.update()

Execution results:

Source material:

2048

The rules of the game are simple. You need to control all the squares moving in the same direction. Two squares with the same number collide and merge into their sum. After each operation, a random 2 or 4 is generated, and a "2048" square is won.
The code is as follows:

import random import sys import pygame from pygame.locals import * PIXEL = 150 SCORE_PIXEL = 100 SIZE = 4 # Classes of Maps class Map: def __init__(self, size): self.size = size self.score = 0 self.map = [[0 for i in range(size)] for i in range(size)] self.add() self.add() # Add 2 or 4, 1/4 probability produces 4 def add(self): while True: p = random.randint(0, self.size * self.size - 1) if self.map[p // self.size][p % self.size] == 0: x = random.randint(0, 3) > 0 and 2 or 4 self.map[p // self.size][p % self.size] = x self.score += x break # The map closes to the left and other directions can be rotated appropriately to return to whether the map is updated or not def adjust(self): changed = False for a in self.map: b = [] last = 0 for v in a: if v != 0: if v == last: b.append(b.pop() << 1) last = 0 else: b.append(v) last = v b += [0] * (self.size - len(b)) for i in range(self.size): if a[i] != b[i]: changed = True a[:] = b return changed # Rotate the map 90 degrees counterclockwise def rotate90(self): self.map = [[self.map[c][r] for c in range(self.size)] for r in reversed(range(self.size))] # Judging Game End def over(self): for r in range(self.size): for c in range(self.size): if self.map[r][c] == 0: return False for r in range(self.size): for c in range(self.size - 1): if self.map[r][c] == self.map[r][c + 1]: return False for r in range(self.size - 1): for c in range(self.size): if self.map[r][c] == self.map[r + 1][c]: return False return True def moveUp(self): self.rotate90() if self.adjust(): self.add() self.rotate90() self.rotate90() self.rotate90() def moveRight(self): self.rotate90() self.rotate90() if self.adjust(): self.add() self.rotate90() self.rotate90() def moveDown(self): self.rotate90() self.rotate90() self.rotate90() if self.adjust(): self.add() self.rotate90() def moveLeft(self): if self.adjust(): self.add() # Update Screen def show(map): for i in range(SIZE): for j in range(SIZE): # Background color block screen.blit(map.map[i][j] == 0 and block[(i + j) % 2] or block[2 + (i + j) % 2], (PIXEL * j, PIXEL * i)) # Numeric Display if map.map[i][j] != 0: map_text = map_font.render(str(map.map[i][j]), True, (106, 90, 205)) text_rect = map_text.get_rect() text_rect.center = (PIXEL * j + PIXEL / 2, PIXEL * i + PIXEL / 2) screen.blit(map_text, text_rect) # Score display screen.blit(score_block, (0, PIXEL * SIZE)) score_text = score_font.render((map.over() and "Game over with score " or "Score: ") + str(map.score), True, (106, 90, 205)) score_rect = score_text.get_rect() score_rect.center = (PIXEL * SIZE / 2, PIXEL * SIZE + SCORE_PIXEL / 2) screen.blit(score_text, score_rect) pygame.display.update() map = Map(SIZE) pygame.init() screen = pygame.display.set_mode((PIXEL * SIZE, PIXEL * SIZE + SCORE_PIXEL)) pygame.display.set_caption("2048") block = [pygame.Surface((PIXEL, PIXEL)) for i in range(4)] # Set Colors block[0].fill((152, 251, 152)) block[1].fill((240, 255, 255)) block[2].fill((0, 255, 127)) block[3].fill((225, 255, 255)) score_block = pygame.Surface((PIXEL * SIZE, SCORE_PIXEL)) score_block.fill((245, 245, 245)) # Set Font map_font = pygame.font.Font(None, PIXEL) score_font = pygame.font.Font(None, SCORE_PIXEL) clock = pygame.time.Clock() show(map) while not map.over(): # 12 as experimental parameter clock.tick(12) for event in pygame.event.get(): if event.type == QUIT: sys.exit() # Receive player action pressed_keys = pygame.key.get_pressed() if pressed_keys[K_w] or pressed_keys[K_UP]: map.moveUp() elif pressed_keys[K_s] or pressed_keys[K_DOWN]: map.moveDown() elif pressed_keys[K_a] or pressed_keys[K_LEFT]: map.moveLeft() elif pressed_keys[K_d] or pressed_keys[K_RIGHT]: map.moveRight() show(map) # Game over pygame.time.delay(3000)

Execution results:

15 March 2020, 13:32 | Views: 9043

Add new comment

For adding a comment, please log in
or create account

0 comments