Learn how to use Python's Pygame module to program computer games and start manipulating gravity.
The real world is full of sports and life. Physics makes real life so busy and dynamic. Physics is the way matter moves in space. Since a computer game world has no matter, it has no laws of physics, and game programmers have to simulate physics.
For most computer games, there are basically only two aspects of physics that are important here: gravity and collision.
When you add an enemy to your game, you implement some collision detection, but this article will add more things 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 sample code and obviously.
Gravity in the real world is the tendency of mass objects to attract each other. The larger the object (mass), the more gravitational force it exerts. In computer game physics, you don’t have to create objects of sufficient mass to prove gravity; you can program in the computer game world itself the tendency of only one object to fall toward the largest hypothetical object.
Add a gravity function
Remember that your player already has an attribute that determines the action. Use this attribute 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 platform games, gravity is selective-if you add gravity to your entire game world, all your platforms will fall to the ground. Conversely, 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 does the player fall
This is a simple function. First, regardless of whether your player wants to move, you set your player to move vertically. That is, you have programmed your players to always drop. This is basically gravity.
In order for the gravity function to take effect, you must call it in your main loop. This way, Python applies the falling motion to your player during each processing loop.
In this code, add the first line to your loop:
player.gravity() #Check gravity
player.update()
Start your game and see what happens. Be careful, because it happens very quickly: you are the player falling from the sky and immediately falling off your game screen.
Your gravitational simulation is working, but maybe too good.
As an experiment, try to change the speed at which your player falls.
Add a floor to gravity
There is no way for your game to discover the problem of your character falling out of the world. In some games, if a player falls out of the world, the sprite is deleted and respawns 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 the screen.
In Python, to check a condition, you can use an if statement.
You must check whether your player is falling, and the extent to which your player is falling. If your player falls to the bottom of the screen, then you can do something. 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 does the player fall
if self.rect.y worldy and self.movey =0:
self.movey =0
self.rect.y = worldy-ty
Then, start your game. Your sprite is still falling, but it stops at the bottom of the screen. However, you may not be able to see your elves above the ground floor. A simple solution is to add another -ty to its new Y position after the sprite collides with the bottom of the game world to make your sprite bounce higher:
def gravity(self):
self.movey +=3.2 #How fast does the player fall
if self.rect.y worldy and self.movey =0:
self.movey =0
self.rect.y = worldy-ty-ty
Now your player bounces at the bottom of the screen, just above your ground sprite.
What your players really need is a way to resist gravity. The problem with gravity is that you can't resist it unless you have something to push away the force of gravity. Therefore, in the next article, you will add ground and platform collision and jumping capabilities. During this period, try to apply gravity to the enemy sprite.
So far, here is the entire code:
#! /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 ofthis 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
'''
classPlatform(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
classPlayer(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.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 +=1if self.frame ani*3:
self.frame =0
self.image = self.images[self.frame//ani]
# moving right
if self.movex 0:
self.frame +=1if 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 -=1print(self.health)
ground_hit_list = pygame.sprite.spritecollide(self, ground_list, False)for g in ground_hit_list:
self.health -=1print(self.health)classEnemy(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 =8if 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 +=1classLevel():
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=0if lvl ==1:while i <len(gloc):
ground =Platform(gloc[i],worldy-ty,tx,ty,'ground.png')
ground_list.add(ground)
i=i+1if lvl ==2:print("Level "+str(lvl))return ground_list
def platform(lvl,tx,ty):
plat_list = pygame.sprite.Group()
ploc =[]
i=0if lvl ==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=0while j <= ploc[i][2]:
plat =Platform((ploc[i][0]+(j*tx)),ploc[i][1],tx,ty,'ground.png')
plat_list.add(plat)
j=j+1print('run'+str(i)+str(ploc[i]))
i=i+1if lvl ==2:print("Level "+str(lvl))return plat_list
'''
Setup
'''
worldx =960
worldy =720
fps =40 # frame rate
ani =4 # animation cycles
clock = 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 move
eloc =[]
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=0while 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)
to sum up
This is the end of this article about simulating gravity in your Python game. For more related content about simulating gravity in your Python game, please search for ZaLou.Cn's previous articles or continue to browse related articles below. Hope everyone Support ZaLou.Cn a lot in the future!
Recommended Posts