Learn how to program computer games using Python’s Pygame module and start manipulating gravity.

The real world is full of movement and life. Physics makes real life so busy and dynamic. Physics is the way matter moves through space. Since a computer game world has no matter, it also has no laws of physics, and programmers using games have to simulate physics.

In most computer games, there are basically only two aspects of physics that are important: gravity and collision.

When you add an enemy to your game, you implement some collision detection, but this article adds more because gravity requires collision detection. Think about why gravity might involve collisions. If you can’t think of any reason, don’t worry — it will work as you develop the sample code and obviously.

In the real world, gravity is the tendency of mass objects to attract each other. The greater the mass, the greater the gravitational effect it exerts. In computer game physics, you don’t have to build something massive enough to prove gravity right; You can program the tendency of just one object to fall toward the hypothetical largest object in the computer game world itself.

Add a gravity function

Remember that your player already has an attribute that determines an action. Use this property to pull the player Sprite to the bottom of the screen.

In Pygame, higher numbers are closer to the bottom edge of the screen.

In the real world, gravity affects everything. However, in platformer, gravity is selective — if you add gravity to your entire game world, all your platforms will fall to the ground. Instead, you can just add gravity to your player and enemy sprites.

First, add a gravity function to your Player class:

Def gravity(self): self.movey += 3.2# How fast the player falls
Copy the code

This is a simple function. First, regardless of whether your player wants to move or not, you set your player up to move vertically. That is, you’ve programmed your players to always fall. That’s basically gravity.

For the gravity function to work, you must call it in your main loop. This way, Python applies the drop motion to your player during each processing loop.

In this code, add the first line to your loop:

    player.gravity() # Check gravity
    player.update()
Copy the code

Launch your game and see what happens. Pay attention, because it happens fast: you’re the player falling out of the sky, right out of your game screen.

Your gravity simulation works, but. maybe too good.

As an experiment, try changing the speed at which your player falls.

Add a floor to gravity

There is no way for your game to detect the problem of your character falling out of the world. In some games, if a player falls out of the world, the Sprite is removed and reborn in a new location. In other games, players lose points or a life. When a player falls out of the world, no matter what you want to happen, you must be able to detect when the player disappears off-screen.

To check a condition in Python, you use an if statement.

You need to check whether your players are dropping, and how much your players are dropping. If your player falls to the bottom of the screen, there are things you can do. To simplify, set the position of the player Sprite to 20 pixels above the bottom edge.

Make your gravity function look like this:

Def gravity(self): self.movey += 3.2# How fast the player falls
       
        if self.rect.y > worldy and self.movey >= 0:
            self.movey = 0
            self.rect.y = worldy-ty
Copy the code

Then, launch your game. Your Sprite still falls, but it stops at the bottom of the screen. However, you may not be able to see your elf above the ground level. A simple solution is to make your Sprite bounce higher by adding another -ty to its new Y position after the Sprite hits the bottom of the game world:

Def gravity(self): self.movey += 3.2# How fast the player falls
       
        if self.rect.y > worldy and self.movey >= 0:
            self.movey = 0
            self.rect.y = worldy-ty-ty
Copy the code

Now your player is bouncing at the bottom of the screen, right above your ground Sprite.

What your players really need is a way to defy gravity. The problem with gravity is, you can’t fight it unless you have something to push it away. Therefore, in the following articles, you will add ground and platform collision and jumping capabilities. In the meantime, try to apply gravity to enemy sprites.

Here’s all the code so far:

#! /usr/bin/env python3
# draw a world
# add a player and player control
# add player movement
# add enemy and basic collision
# add platform
# add gravity

# GNU All-Permissive License
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved. This file is offered as-is,
# without any warranty.

import pygame
import sys
import os

' ''
Objects
'' '

class Platform(pygame.sprite.Sprite):
    # x location, y location, img width, img height, img file    
    def __init__(self,xloc,yloc,imgw,imgh,img):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(os.path.join('images',img)).convert()
        self.image.convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.y = yloc
        self.rect.x = xloc

class Player(pygame.sprite.Sprite):
    ' '' Spawn a player '' '
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.movex = 0
        self.movey = 0
        self.frame = 0
        self.health = 10
        self.score = 1
        self.images = []
        for i inRange (1, 9) : img = pygame. Image. The load (OS) path) join ('images'.'hero' + str(i) + '.png')).convert() img.convert_alpha() img.set_colorkey(ALPHA) self.images.append(img) self.image = self.images[0] self.rect = Self.image.get_rect () def gravity(self): self.movey += 3.2# how fast player falls
       
        if self.rect.y > worldy and self.movey >= 0:
            self.movey = 0
            self.rect.y = worldy-ty-ty
       
    def control(self,x,y):
        ' '' control player movement '' '
        self.movex += x
        self.movey += y
       
    def update(self):
        ' '' Update sprite position '' '

        self.rect.x = self.rect.x + self.movex
        self.rect.y = self.rect.y + self.movey

        # moving left
        if self.movex < 0:
            self.frame += 1
            if self.frame > ani*3:
                self.frame = 0
            self.image = self.images[self.frame//ani]

        # moving right
        if self.movex > 0:
            self.frame += 1
            if self.frame > ani*3:
                self.frame = 0
            self.image = self.images[(self.frame//ani)+4]

        # collisions
        enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False)
        for enemy in enemy_hit_list:
            self.health -= 1
            print(self.health)

        ground_hit_list = pygame.sprite.spritecollide(self, ground_list, False)
        for g in ground_hit_list:
            self.health -= 1
            print(self.health)

class Enemy(pygame.sprite.Sprite):
    ' '' Spawn an enemy '' '
    def __init__(self,x,y,img):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(os.path.join('images',img))
        #self.image.convert_alpha()
        #self.image.set_colorkey(ALPHA)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.counter = 0
       
    def move(self):
        ' '' enemy movement '' '
        distance = 80
        speed = 8

        if self.counter >= 0 and self.counter <= distance:
            self.rect.x += speed
        elif self.counter >= distance and self.counter <= distance*2:
            self.rect.x -= speed
        else:
            self.counter = 0

        self.counter += 1

class Level():
    def bad(lvl,eloc):
        if lvl == 1:
            enemy = Enemy(eloc[0],eloc[1],'yeti.png') # spawn enemy
            enemy_list = pygame.sprite.Group() # create enemy group
            enemy_list.add(enemy)              # add enemy to group
           
        if lvl == 2:
            print("Level " + str(lvl) )

        return enemy_list

    def loot(lvl,lloc):
        print(lvl)

    def ground(lvl,gloc,tx,ty):
        ground_list = pygame.sprite.Group()
        i=0
        if lvl == 1:
            while i < len(gloc):
                ground = Platform(gloc[i],worldy-ty,tx,ty,'ground.png')
                ground_list.add(ground)
                i=i+1

        if lvl == 2:
            print("Level " + str(lvl) )

        return ground_list

    def platform(lvl,tx,ty):
        plat_list = pygame.sprite.Group()
        ploc = []
        i=0
        ifLVL == 1: ploc.append((0,worldy-ty-128,3)) ploc.append((300,worldy-ty-256,3)) ploc.append((500,worldy-ty-128,4))while i < len(ploc):
                j=0
                while j <= ploc[i][2]:
                    plat = Platform((ploc[i][0]+(j*tx)),ploc[i][1],tx,ty,'ground.png')
                    plat_list.add(plat)
                    j=j+1
                print('run' + str(i) + str(ploc[i]))
                i=i+1

        if lvl == 2:
            print("Level " + str(lvl) )

        return plat_list

' ''
Setup
'' '
worldx = 960
worldy = 720

fps = 40 # frame rate
ani = 4  # animation cyclesClock = pygame.time.clock () pygame.init() main = True BLUE = (25,25,200) BLACK = (23,23,23) WHITE = (254,254,254) ALPHA = (0,255,0) world = pygame.display.set_mode([worldx,worldy]) backdrop = pygame.image.load(os.path.join('images'.'stage.png')).convert()
backdropbox = world.get_rect()
player = Player() # spawn player
player.rect.x = 0
player.rect.y = 0
player_list = pygame.sprite.Group()
player_list.add(player)
steps = 10 # how fast to moveEloc = [] eloc = [200,20] gloc = []#gloc = [0,630,64,630,128,630,192,630,256,630,320,630,384,630]
tx = 64 #tile size
ty = 64 #tile size

i=0
while i <= (worldx/tx)+tx:
    gloc.append(i*tx)
    i=i+1

enemy_list = Level.bad( 1, eloc )
ground_list = Level.ground( 1,gloc,tx,ty )
plat_list = Level.platform( 1,tx,ty )

' ''
Main loop
'' '
while main == True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit(); sys.exit()
            main = False

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT or event.key == ord('a') :print("LEFT")
                player.control(-steps,0)
            if event.key == pygame.K_RIGHT or event.key == ord('d') :print("RIGHT")
                player.control(steps,0)
            if event.key == pygame.K_UP or event.key == ord('w') :print('jump')

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == ord('a'):
                player.control(steps,0)
            if event.key == pygame.K_RIGHT or event.key == ord('d'):
                player.control(-steps,0)
            if event.key == pygame.K_UP or event.key == ord('w') :print('jump')

            if event.key == ord('q'):
                pygame.quit()
                sys.exit()
                main = False

    world.blit(backdrop, backdropbox)
    player.gravity() # check gravity
    player.update()
    player_list.draw(world)
    enemy_list.draw(world)
    ground_list.draw(world)
    plat_list.draw(world)
    for e in enemy_list:
        e.move()
    pygame.display.flip()
    clock.tick(fps)
Copy the code

This is still in progress in part 7 on creating computer games in Python 3 using the Pygame module. The previous article was:

  • Learn how to program in Python by building a simple dice game
  • Build a game framework using Python and Pygame modules
  • How to add a player to your Python game
  • Use Pygame to make your game character move
  • How do you add an enemy to your Python game
  • Place platforms in Pygame games

Via: opensource.com/article/19/…

By Seth Kenlon (lujun9972

This article is originally compiled by LCTT and released in Linux China