Posts: 5,151
Threads: 396
Joined: Sep 2016
Nov-05-2017, 11:55 PM
(This post was last modified: Feb-01-2020, 07:30 PM by metulburr.)
This thread is a series of posts that include an example that are commonly asked on the forum. It is more efficient to make a thread containing them all then write them up upon each request. The posts are in no particular order. These get appended with new examples every time i repeatedly post one for more than one person. You can often make a small change to accommodate what you are doing with these examples. There are even more and more detailed examples at Mekire repos.
Recommended Tutorials:
Posts: 5,151
Threads: 396
Joined: Sep 2016
Time: Do something every second
This example shows a random number every second
import pygame as pg
import random
pg.init()
screen = pg.display.set_mode((800,600))
screen_rect = screen.get_rect()
clock = pg.time.Clock()
done = False
class Number:
def __init__(self):
self.timer = 0.0
self.delay = 1000
self.new_num()
def new_num(self):
num = random.randint(1,100)
self.image, self.rect = self.make_text(str(num), (255,0,0), screen_rect.center, 75, 'Ariel')
def make_text(self,message,color,center,size, fonttype):
font = pg.font.SysFont(fonttype, size)
text = font.render(message,True,color)
rect = text.get_rect(center=center)
return text,rect
def update(self):
if pg.time.get_ticks()-self.timer > self.delay:
self.timer = pg.time.get_ticks()
self.new_num()
def draw(self, surf):
surf.blit(self.image, self.rect)
num = Number()
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
screen.fill((0,0,0))
num.update()
num.draw(screen)
pg.display.update()
clock.tick(60)
Recommended Tutorials:
Posts: 5,151
Threads: 396
Joined: Sep 2016
Delta Time Movement
import sys
import math
import pygame as pg
class Block(pg.sprite.Sprite):
def __init__(self, pos, speed):
self.image = pg.Surface((50,50)).convert()
self.image.fill(pg.Color("red"))
self.rect = self.image.get_rect(center=pos)
self.exact_position = list(self.rect.center)
self.speed = speed #Pixels per second
self.target = None
self.vec = None
self.distance = None
def update(self, dt):
if self.target:
travelled = math.hypot(self.vec[0]*dt, self.vec[1]*dt)
self.distance -= travelled
if self.distance <= 0:
self.rect.center = self.exact_position = self.target
self.target = None
else:
self.exact_position[0] += self.vec[0]*dt
self.exact_position[1] += self.vec[1]*dt
self.rect.center = self.exact_position
def draw(self, surface):
surface.blit(self.image, self.rect)
def get_new_instruction(self, target):
x = target[0]-self.exact_position[0]
y = target[1]-self.exact_position[1]
self.distance = math.hypot(x, y)
try:
self.vec = self.speed*x/self.distance, self.speed*y/self.distance
self.target = list(target)
except ZeroDivisionError:
pass
class Control(object):
def __init__(self):
pg.init()
pg.display.set_caption("Move To Target")
self.screen = pg.display.set_mode((500,500))
self.screen_rect = self.screen.get_rect()
self.clock = pg.time.Clock()
self.fps = 60.0
self.done = False
self.player = Block(self.screen_rect.center, 500)
def event_loop(self):
for event in pg.event.get():
if event.type == pg.QUIT:
self.done = True
elif event.type == pg.MOUSEBUTTONDOWN:
if event.button == 1:
self.player.get_new_instruction(event.pos)
def update(self, dt):
self.player.update(dt)
def draw(self):
self.screen.fill((30,40,50))
self.player.draw(self.screen)
def main_loop(self):
while not self.done:
dt = self.clock.tick(self.fps)/1000.0
self.event_loop()
self.update(dt)
self.draw()
pg.display.update()
def main():
app = Control()
app.main_loop()
pg.quit()
sys.exit()
if __name__ == "__main__":
main()
Recommended Tutorials:
Posts: 5,151
Threads: 396
Joined: Sep 2016
Simple Pong
This example has a single ball and paddle. It shows how to handle ball bouncing as well as the paddle movement.
import pygame as pg
import random
screen = pg.display.set_mode((800,600))
screen_rect = screen.get_rect()
clock = pg.time.Clock()
done = False
class Ball:
def __init__(self, screen_rect, size):
self.screen_rect = screen_rect
self.height, self.width = size
self.image = pg.Surface(size).convert()
self.image.fill((255,0,0))
self.rect = self.image.get_rect()
self.speed = 5
self.set_ball()
def get_random_float(self):
'''get float for velocity of ball on starting direction'''
while True:
num = random.uniform(-1.0, 1.0)
if num > -.5 and num < .5: #restrict ball direction to avoid infinity bounce
continue
else:
return num
def set_ball(self):
'''get random starting direction and set ball to center screen'''
x = self.get_random_float()
y = self.get_random_float()
self.vel = [x, y]
self.rect.center = self.screen_rect.center
self.true_pos = list(self.rect.center)
def collide_walls(self):
if self.rect.y < 0 or self.rect.y > self.screen_rect.bottom - self.height:
self.vel[1] *= -1;
if self.rect.x < 0 or self.rect.x > self.screen_rect.right- self.height:
self.vel[0] *= -1;
print('side wall hit, time to reset ball and give points')
def collide_paddle(self, paddle_rect):
if self.rect.colliderect(paddle_rect):
self.vel[0] *= -1;
def move(self):
self.true_pos[0] += self.vel[0] * self.speed
self.true_pos[1] += self.vel[1] * self.speed
self.rect.center = self.true_pos
def update(self, paddle_rect):
self.collide_walls()
self.collide_paddle(paddle_rect)
self.move()
def render(self, screen):
screen.blit(self.image, self.rect)
class Paddle:
def __init__(self, screen_rect, size):
self.screen_rect = screen_rect
self.image = pg.Surface(size).convert()
self.image.fill((255,255,0))
self.rect = self.image.get_rect()
self.rect.x += 25 #spacer from wall
self.speed = 5
def move(self, x, y):
self.rect[0] += x * self.speed
self.rect[1] += y * self.speed
def update(self, keys):
self.rect.clamp_ip(self.screen_rect)
if keys[pg.K_UP] or keys[pg.K_w]:
self.move(0, -1)
if keys[pg.K_DOWN] or keys[pg.K_s]:
self.move(0, 1)
def render(self, screen):
screen.blit(self.image, self.rect)
paddle = Paddle(screen_rect, (25,100))
ball = Ball(screen_rect, (25,25))
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
keys = pg.key.get_pressed()
screen.fill((0,0,0))
paddle.update(keys)
ball.update(paddle.rect)
paddle.render(screen)
ball.render(screen)
clock.tick(60)
pg.display.update()
Recommended Tutorials:
Posts: 5,151
Threads: 396
Joined: Sep 2016
Rotate Object
This example shows a constant rotating object. This shows how to rotate an object as well as how to not obscure it by using a master image to rotate instead of the previous rotated image to rotate. This is a big deal because an image rotated can get distorrted if not done this way.
import pygame as pg
screen = pg.display.set_mode((800,600))
screen_rect = screen.get_rect()
clock = pg.time.Clock()
done = False
class Rotator:
def __init__(self, screen_rect):
self.screen_rect = screen_rect
self.master_image = pg.Surface([100,100]).convert_alpha()
self.master_image.fill((255,0,0))
self.image = self.master_image.copy()
self.rect = self.image.get_rect(center=self.screen_rect.center)
self.delay = 10
self.timer = 0.0
self.angle = 0
def new_angle(self):
self.angle += 1
self.angle %= 360
def rotate(self):
self.new_angle()
self.image = pg.transform.rotate(self.master_image, self.angle)
self.rect = self.image.get_rect(center=self.screen_rect.center)
def update(self):
if pg.time.get_ticks()- self.timer > self.delay:
self.timer = pg.time.get_ticks()
self.rotate()
def draw(self, surf):
surf.blit(self.image, self.rect)
rotator = Rotator(screen_rect)
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
screen.fill((0,0,0))
rotator.update()
rotator.draw(screen)
pg.display.update() more information on this thread regarding rotating.
Recommended Tutorials:
Posts: 5,151
Threads: 396
Joined: Sep 2016
Feb-01-2020, 07:26 PM
(This post was last modified: Feb-01-2020, 07:26 PM by metulburr.)
Shrink and Expand Image
https://python-forum.io/attachment.php?aid=271
An example of shrinking and expanding an image based on mouse position on the screen
import pygame as pg
class Player:
def __init__(self, screen_rect):
self.screen_rect = screen_rect
self.image_orig = pg.image.load("default.png")
self.image = self.image_orig.copy()
self.rect = self.image.get_rect(center=screen_rect.center)
def update(self):
x,y = pg.mouse.get_pos()
self.image = pg.transform.scale(self.image_orig, (x,y))
self.rect = self.image.get_rect(center=self.screen_rect.center)
def draw(self, surf):
surf.blit(self.image, self.rect)
screen = pg.display.set_mode((800,600))
screen_rect = screen.get_rect()
done = False
player = Player(screen_rect)
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
screen.fill((0,0,0))
player.update()
player.draw(screen)
pg.display.update()
Recommended Tutorials:
Posts: 5,151
Threads: 396
Joined: Sep 2016
Credit Screen
This is a basic credit screen like the end of a movie that scrolls text by vertically
import pygame as pg
pg.init()
text_list = '''I'm Henry the eighth, I am
Henry the eighth, I am, I am
I got married to the widow next door
She's been married seven times before
And every one was an Henry (Henry)
She wouldn't have a Willy or a Sam (No Sam)
I'm her eighth old man, I'm Henry
Henry the eighth I am
Second verse, same as the first
I'm Henry the eighth, I am
Henry the eighth, I am, I am
I got married to the widow next door
She's been married seven times before
And every one was an Henry (Henry)
She wouldn't have a Willy or a Sam (No Sam)
I'm her eighth old man, I'm Henry
Henry the eighth I am
I'm Henry the eighth, I am
Henry the eighth, I am, I am
I got married to the widow next door
She's been married seven times before
And every one was an Henry (Henry)
She wouldn't have a Willy or a Sam (No Sam)
I'm her eighth old man, I'm Henry
Henry the eighth I am
H-E-N-R-Y
Henry (Henry)
Henry (Henry)
Henry the eighth I am, I am
Henry the eighth I am
Yeah!
'''.split('\n')
class Credits:
def __init__(self, screen_rect, lst):
self.srect = screen_rect
self.lst = lst
self.size = 16
self.color = (255,0,0)
self.buff_centery = self.srect.height/2 + 5
self.buff_lines = 50
self.timer = 0.0
self.delay = 50
self.make_surfaces()
def make_text(self,message):
font = pg.font.SysFont('Arial', self.size)
text = font.render(message,True,self.color)
rect = text.get_rect(center = (self.srect.centerx, self.srect.centery + self.buff_centery) )
return text,rect
def make_surfaces(self):
self.text = [ ]
for i, line in enumerate(self.lst):
l = self.make_text(line)
l[1].y += i*self.buff_lines
self.text.append(l)
def update(self):
if pg.time.get_ticks()-self.timer > self.delay:
self.timer = pg.time.get_ticks()
for text, rect in self.text:
rect.y -= 1
def render(self, surf):
for text, rect in self.text:
surf.blit(text, rect)
screen = pg.display.set_mode((800,600))
screen_rect = screen.get_rect()
clock = pg.time.Clock()
done = False
cred = Credits(screen_rect, text_list)
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
screen.fill((0,0,0))
cred.update()
cred.render(screen)
pg.display.update()
clock.tick(60)
Recommended Tutorials:
Posts: 5,151
Threads: 396
Joined: Sep 2016
Character Jump
This example is a rectangle that jumps and moves around the screen with WASD and SPACEBAR. You can easily attach a spritesheet to animate to the position of the rectangle and draw it over that position.
import pygame as pg
class Player:
def __init__(self, screen_rect):
self.screen_rect = screen_rect
self.width = 50
self.height = 75
self.image = pg.Surface([self.width, self.height])
self.image.fill((255,255,255))
starting_loc = (0, screen_rect.height)
self.rect = self.image.get_rect(bottomleft=starting_loc)
self.speed = 5
self.grav = .5
self.jumping = False
self.y_vel = 0
def update(self):
self.rect.clamp_ip(self.screen_rect)
self.jump_update()
def render(self, screen):
screen.blit(self.image, self.rect)
def move(self, x, y):
self.rect.x += x * self.speed
self.rect.y += y * self.speed
def jump_update(self):
if self.jumping:
self.y_vel += self.grav
self.rect.y += self.y_vel
if self.is_touching_ground():
self.jumping = False
def is_touching_ground(self):
return self.rect.y >= self.screen_rect.height - self.height
def jump(self):
if not self.jumping:
self.y_vel = -12
self.jumping = True
class Control:
def __init__(self):
self.screensize = (600,400)
self.screen = pg.display.set_mode(self.screensize)
self.screen_rect = self.screen.get_rect()
self.clock = pg.time.Clock()
self.fps = 60
self.quit = False
self.keys = pg.key.get_pressed()
self.player = Player(self.screen_rect)
def run(self):
while not self.quit:
now = pg.time.get_ticks()
self.held_keys(self.keys)
self.event_loop()
self.update()
self.render()
pg.display.update()
self.clock.tick(self.fps)
def event_loop(self):
for event in pg.event.get():
if event.type == pg.QUIT:
self.quit = True
elif event.type in (pg.KEYDOWN, pg.KEYUP):
self.keys = pg.key.get_pressed()
if event.type == pg.KEYDOWN:
if event.key == pg.K_SPACE:
self.player.jump()
def held_keys(self, keys):
if keys[pg.K_a]:
self.player.move(-1, 0)
if keys[pg.K_d]:
self.player.move(1, 0)
def render(self):
self.screen.fill((0,0,0))
self.player.render(self.screen)
def update(self):
self.player.update()
app = Control()
app.run()
Recommended Tutorials:
Posts: 5,151
Threads: 396
Joined: Sep 2016
Basic Pause Feature
This example does not show anything on the screen. However it uses prints to show what is happening based on whether the game is paused or not. Use P to switch between states.
import pygame as pg
class Control:
def __init__(self):
self.screen_size = (600,400)
self.screen = pg.display.set_mode(self.screen_size)
self.done = False
self.pause = False
def run(self):
while not self.done:
self.get_events()
if not self.pause:
self.update()
self.render()
print('executing update functions and render functions')
else:
print('pause update and render')
def get_events(self):
for event in pg.event.get():
if event.type == pg.QUIT:
self.done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_p:
self.pause = not self.pause
def update(self):
pass
def render(self):
self.screen.fill((0,0,0))
pg.display.update()
app = Control()
app.run()
Recommended Tutorials:
Posts: 5,151
Threads: 396
Joined: Sep 2016
Rotate to Mouse Position
import pygame as pg
import math
class Rotator:
def __init__(self, screen_rect):
self.orig_image = pg.Surface([10,100]).convert_alpha() #
self.image = self.orig_image
self.image.fill((255,255,255))
self.rect = self.image.get_rect(center=screen_rect.center)
self.angle = 0
self.distance = 0
self.angle_offset = 0
def render(self, screen):
screen.blit(self.image, self.rect)
def get_angle(self):
mouse = pg.mouse.get_pos()
offset = (self.rect.centerx-mouse[0],self.rect.centery-mouse[1])
self.angle = math.degrees(math.atan2(*offset)) - self.angle_offset
old_center = self.rect.center
self.image = pg.transform.rotate(self.orig_image, self.angle)
self.rect = self.image.get_rect(center=old_center)
self.distance = math.sqrt((offset[0] * offset[0]) + (offset[1] * offset[1]))
def update(self):
self.get_angle()
self.display = 'angle:{:.2f} disatance:{:.2f}'.format(self.angle, self.distance)
if __name__ == '__main__':
running = True
pg.init()
screen = pg.display.set_mode((600,400))
screen_rect = screen.get_rect()
rotator = Rotator(screen_rect)
clock = pg.time.Clock()
while running:
screen.fill((0,0,0))
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
rotator.update()
rotator.render(screen)
pg.display.set_caption(rotator.display)
pg.display.update()
clock.tick(60)
Recommended Tutorials:
|