Science and technology

Simulate gravity in your Python recreation

The actual world is stuffed with motion and life. The factor that makes the true world so busy and dynamic is physics. Physics is the best way matter strikes via area. Since a online game world has regardless of, it additionally has no physics, so recreation programmers need to simulate physics.

In phrases of most video video games, there are mainly solely two points of physics which can be essential: gravity and collision.

You applied some collision detection if you added an enemy to your recreation, however this text provides extra as a result of gravity requires collision detection. Think about why gravity would possibly contain collisions. If you may’t consider any causes, don’t be concerned—it will grow to be obvious as you’re employed via the pattern code.

Gravity in the true world is the tendency for objects with mass to be drawn towards each other. The bigger the thing, the extra gravitational affect it exerts. In online game physics, you do not have to create objects with mass nice sufficient to justify a gravitational pull; you may simply program a bent for objects to fall towards the presumed largest object within the online game world: the world itself.

Adding a gravity perform

Remember that your participant already has a property to find out movement. Use this property to drag the participant sprite towards the underside of the display.

In Pygame, greater numbers are nearer to the underside fringe of the display.

In the true world, gravity impacts every thing. In platformers, nevertheless, gravity is selective—when you add gravity to your complete recreation world, all your platforms would fall to the bottom. Instead, you add gravity simply to your participant and enemy sprites.

First, add a gravity perform in your Player class:

    def gravity(self):
        self.movey += three.2 # how briskly participant falls

This is a straightforward perform. First, you set your participant in vertical movement, whether or not your participant desires to be in movement or not. In different phrases, you could have programmed your participant to all the time be falling. That’s mainly gravity.

For the gravity perform to have an impact, it’s essential to name it in your most important loop. This manner, Python applies the falling movement to your participant as soon as each clock tick.

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

    participant.gravity() # test gravity
    participant.replace()

Launch your recreation to see what occurs. Look sharp, as a result of it occurs quick: your participant falls out of the sky, proper off your recreation display.

Your gravity simulation is working, however possibly too nicely.

As an experiment, attempt altering the speed at which your participant falls.

Adding a ground to gravity

The drawback along with your character falling off the world is that there isn’t any manner to your recreation to detect it. In some video games, if a participant falls off the world, the sprite is deleted and respawned someplace new. In different video games, the participant loses factors or a life. Whatever you wish to occur when a participant falls off the world, you could have to have the ability to detect when the participant disappears offscreen.

In Python, to test for a situation, you should use an if assertion.

You should test to see if your participant is falling and the way far your participant has fallen. If your participant falls thus far that it reaches the underside of the display, then you are able to do one thing. To preserve issues easy, set the place of the participant sprite to 20 pixels above the underside edge.

Make your gravity perform appear like this:

    def gravity(self):
        self.movey += three.2 # how briskly participant falls
       
        if self.rect.y > worldy and self.movey >= zero:
            self.movey = zero
            self.rect.y = worldy-ty

Then launch your recreation. Your sprite nonetheless falls, however it stops on the backside of the display. You might not be capable of see your sprite behind the bottom layer, although. An straightforward repair is to make your participant sprite bounce greater by including one other -ty to its new Y place after it hits the underside of the sport world:

    def gravity(self):
        self.movey += three.2 # how briskly participant falls
       
        if self.rect.y > worldy and self.movey >= zero:
            self.movey = zero
            self.rect.y = worldy-ty-ty

Now your participant bounces on the backside of the display, simply behind your floor sprites.

What your participant actually wants is a strategy to battle gravity. The drawback with gravity is, you may’t battle it except you could have one thing to push off of. So, within the subsequent article, you may add floor and platform collision and the flexibility to leap. In the meantime, attempt making use of gravity to the enemy sprite.

Here’s all of the code thus far:

#!/usr/bin/env python3
# draw a world
# add a participant and participant management
# add participant motion
# add enemy and primary collision
# add platform
# add gravity

# GNU All-Permissive License
# Copying and distribution of this file, with or with out modification,
# are permitted in any medium with out royalty offered the copyright
# discover and this discover are preserved.  This file is obtainable as-is,
# with none guarantee.

import pygame
import sys
import os

'''
Objects
'''

class Platform(pygame.sprite.Sprite):
    # x location, y location, img width, img top, img file    
    def __init__(self,xloc,yloc,imgw,imgh,img):
        pygame.sprite.Sprite.__init__(self)
        self.picture = pygame.picture.load(os.path.be a part of('photos',img)).convert()
        self.picture.convert_alpha()
        self.rect = self.picture.get_rect()
        self.rect.y = yloc
        self.rect.x = xloc

class Player(pygame.sprite.Sprite):
    '''
    Spawn a participant
    '''

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.movex = zero
        self.movey = zero
        self.body = zero
        self.well being = 10
        self.rating = 1
        self.photos = []
        for i in vary(1,9):
            img = pygame.picture.load(os.path.be a part of('photos','hero' + str(i) + '.png')).convert()
            img.convert_alpha()
            img.set_colorkey(ALPHA)
            self.photos.append(img)
            self.picture = self.photos[zero]
            self.rect  = self.picture.get_rect()

    def gravity(self):
        self.movey += three.2 # how briskly participant falls
       
        if self.rect.y > worldy and self.movey >= zero:
            self.movey = zero
            self.rect.y = worldy-ty-ty
       
    def management(self,x,y):
        '''
        management participant motion
        '''

        self.movex += x
        self.movey += y
       
    def replace(self):
        '''
        Update sprite place
        '''

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

        # shifting left
        if self.movex < zero:
            self.body += 1
            if self.body > ani*three:
                self.body = zero
            self.picture = self.photos[self.body//ani]

        # shifting proper
        if self.movex > zero:
            self.body += 1
            if self.body > ani*three:
                self.body = zero
            self.picture = self.photos[(self.body//ani)+four]

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

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

class Enemy(pygame.sprite.Sprite):
    '''
    Spawn an enemy
    '''

    def __init__(self,x,y,img):
        pygame.sprite.Sprite.__init__(self)
        self.picture = pygame.picture.load(os.path.be a part of('photos',img))
        #self.picture.convert_alpha()
        #self.picture.set_colorkey(ALPHA)
        self.rect = self.picture.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.counter = zero
       
    def transfer(self):
        '''
        enemy motion
        '''

        distance = 80
        velocity = eight

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

        self.counter += 1

class Level():
    def unhealthy(lvl,eloc):
        if lvl == 1:
            enemy = Enemy(eloc[zero],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 floor(lvl,gloc,tx,ty):
        ground_list = pygame.sprite.Group()
        i=zero
        if lvl == 1:
            whereas i < len(gloc):
                floor = Platform(gloc[i],worldy-ty,tx,ty,'floor.png')
                ground_list.add(floor)
                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=zero
        if lvl == 1:
            ploc.append((zero,worldy-ty-128,three))
            ploc.append((300,worldy-ty-256,three))
            ploc.append((500,worldy-ty-128,four))

            whereas i < len(ploc):
                j=zero
                whereas j <= ploc[i][2]:
                    plat = Platform((ploc[i][zero]+(j*tx)),ploc[i][1],tx,ty,'floor.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 # body price
ani = four  # animation cycles
clock = pygame.time.Clock()
pygame.init()
most important = True

BLUE  = (25,25,200)
BLACK = (23,23,23 )
WHITE = (254,254,254)
ALPHA = (zero,255,zero)

world = pygame.show.set_mode([worldx,worldy])
backdrop = pygame.picture.load(os.path.be a part of('photos','stage.png')).convert()
backdropbox = world.get_rect()
participant = Player() # spawn participant
participant.rect.x = zero
participant.rect.y = zero
player_list = pygame.sprite.Group()
player_list.add(participant)
steps = 10 # how briskly to maneuver

eloc = []
eloc = [200,20]
gloc = []
#gloc = [0,630,64,630,128,630,192,630,256,630,320,630,384,630]
tx = 64 #tile dimension
ty = 64 #tile dimension

i=zero
whereas i <= (worldx/tx)+tx:
    gloc.append(i*tx)
    i=i+1

enemy_list = Level.unhealthy( 1, eloc )
ground_list = Level.floor( 1,gloc,tx,ty )
plat_list = Level.platform( 1,tx,ty )

'''
Main loop
'''

whereas most important == True:
    for occasion in pygame.occasion.get():
        if occasion.kind == pygame.QUIT:
            pygame.give up(); sys.exit()
            most important = False

        if occasion.kind == pygame.KEYDOWN:
            if occasion.key == pygame.K_LEFT or occasion.key == ord('a'):
                print("LEFT")
                participant.management(-steps,zero)
            if occasion.key == pygame.K_RIGHT or occasion.key == ord('d'):
                print("RIGHT")
                participant.management(steps,zero)
            if occasion.key == pygame.K_UP or occasion.key == ord('w'):
                print('soar')

        if occasion.kind == pygame.KEYUP:
            if occasion.key == pygame.K_LEFT or occasion.key == ord('a'):
                participant.management(steps,zero)
            if occasion.key == pygame.K_RIGHT or occasion.key == ord('d'):
                participant.management(-steps,zero)
            if occasion.key == pygame.K_UP or occasion.key == ord('w'):
                print('soar')

            if occasion.key == ord('q'):
                pygame.give up()
                sys.exit()
                most important = False

    world.blit(backdrop, backdropbox)
    participant.gravity() # test gravity
    participant.replace()
    player_list.draw(world)
    enemy_list.draw(world)
    ground_list.draw(world)
    plat_list.draw(world)
    for e in enemy_list:
        e.transfer()
    pygame.show.flip()
    clock.tick(fps)


This is an element 6 in an ongoing collection about creating video video games in Python 3 utilizing the Pygame module. Previous articles are:

Most Popular

To Top