This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
en:pygame:step005 [2014/01/09 11:07] 127.0.0.1 external edit |
en:pygame:step005 [2020/05/15 22:39] (current) horst |
||
---|---|---|---|
Line 3: | Line 3: | ||
====== Step 005 - Frame-based Movement ====== | ====== Step 005 - Frame-based Movement ====== | ||
- | | {{:en:part2: | + | | {{part2: |
| simple version | | simple version | ||
Line 108: | Line 108: | ||
with the " | with the " | ||
- | //click reload in your browser if you see no code here:// | + | <code python> |
- | < | + | #!/usr/bin/env python |
- | < | + | """ |
- | </script>< | + | 005_bouncing_ball_frame_based.py |
+ | bouncing ball and pulsating circle | ||
+ | url: http://thepythongamebook.com/en:part2:pygame:step005 | ||
+ | author: horst.jens@spielend-programmieren.at | ||
+ | licence: gpl, see http://www.gnu.org/ | ||
+ | works with python3.4 and python2.7 | ||
+ | |||
+ | bouncing ball. each frame the complete screen is filled with the background, | ||
+ | making this example simple to code but possible slow on larger resolutions. | ||
+ | Each frame, a random-coloured circle is drawn with randomized radius directly on the screen. | ||
+ | Try to manipulate the display.set_mode values to change the resolution.""" | ||
+ | #the next line is only needed for python2.x and not necessary for python3.x | ||
+ | from __future__ import print_function, | ||
+ | import pygame | ||
+ | import random | ||
+ | pygame.init() | ||
+ | screen=pygame.display.set_mode((640, | ||
+ | screenrect = screen.get_rect() | ||
+ | # ------ constants ------------ | ||
+ | clock = pygame.time.Clock() | ||
+ | mainloop = True | ||
+ | FPS = 30 # desired framerate in frames per second. | ||
+ | playtime = 0 | ||
+ | radius = 50 # for pulsating circle | ||
+ | dr = 1 # change of radius in pixel per frame | ||
+ | # ------- background --------- | ||
+ | background = pygame.Surface(screen.get_size()) | ||
+ | background.fill((255, | ||
+ | background = background.convert() | ||
+ | screen.blit(background, | ||
+ | # -------- bouncing ball surface --------- | ||
+ | ballsurface = pygame.Surface((50, | ||
+ | ballsurface.set_colorkey((0, | ||
+ | # | ||
+ | pygame.draw.circle(ballsurface, | ||
+ | ballsurface = ballsurface.convert_alpha() | ||
+ | ballrect = ballsurface.get_rect() # the rectangle of the ball surface, for collision detection | ||
+ | ballx, bally = 550, 240 # start position of the ball (x,y) | ||
+ | dx = 10 # x speed vector of the ball in pixel per frame | ||
+ | dy = 0 # y speed vector of the ball in pixel per frame | ||
+ | # ----------- bouncing ball (drawing) ------ | ||
+ | x1 = 50 | ||
+ | y1 = 200 | ||
+ | dx1 = 7 | ||
+ | dy1 = 0 | ||
+ | radius1 = 40 | ||
+ | # --------- static big blue ball ----------- | ||
+ | pygame.draw.circle(background, | ||
+ | # --------- mainloop ---------- | ||
+ | while mainloop: | ||
+ | # do all this each frame | ||
+ | milliseconds = clock.tick(FPS) # do not go faster than this framerate | ||
+ | playtime += milliseconds / 1000.0 | ||
+ | for event in pygame.event.get(): | ||
+ | if event.type == pygame.QUIT: | ||
+ | mainloop = False # pygame window closed by user | ||
+ | elif event.type == pygame.KEYDOWN: | ||
+ | if event.key == pygame.K_ESCAPE: | ||
+ | mainloop = False # user pressed ESC | ||
+ | pygame.display.set_caption(" | ||
+ | " | ||
+ | # ----- clean screen ---------- | ||
+ | screen.blit(background, | ||
+ | # ------- bouncing ball (drawing) --------- | ||
+ | x1 += dx1 | ||
+ | if x1 + radius1 >= screenrect.width: | ||
+ | x1 = screenrect.width - radius1 | ||
+ | dx1 *= -1 | ||
+ | elif x1 - radius1 <= 0: | ||
+ | x1 = radius1 | ||
+ | dx1 *= -1 | ||
+ | pygame.draw.circle(screen, | ||
+ | # -------- bouncing ball surface ---------- | ||
+ | ballx += dx | ||
+ | bally += dy | ||
+ | if ballx < 0: # bounce ball if out of screen | ||
+ | ballx = 0 | ||
+ | dx *= -1 | ||
+ | elif ballx + ballrect.width > screenrect.width: | ||
+ | ballx = screenrect.width - ballrect.width | ||
+ | dx *= -1 | ||
+ | screen.blit(ballsurface, | ||
+ | # ----- pulsating circle ----------- | ||
+ | colour = (random.randint(0, | ||
+ | if radius >100 or radius < 5: | ||
+ | dr *= -1 | ||
+ | radius += dr | ||
+ | pygame.draw.circle(screen, | ||
+ | # --------- flip screen ------------------ | ||
+ | pygame.display.flip() | ||
+ | print(" | ||
+ | |||
+ | </ | ||
==== Pretty Version ==== | ==== Pretty Version ==== | ||
Line 122: | Line 214: | ||
* https:// | * https:// | ||
- | //click reload in your browser if you see no code here:// | + | |
- | < | + | <code python> |
- | <script src=" | + | #!/usr/bin/env python |
- | </script></html> | + | |
+ | """ | ||
+ | Name : blit_pulse2.py | ||
+ | URL : http://thepythongamebook.com/en: | ||
+ | Author : yipyip | ||
+ | Licence: gpl, see http://www.gnu.org/licenses/gpl.html | ||
+ | |||
+ | works with pyhton3.4 and python2.7 | ||
+ | """ | ||
+ | |||
+ | #### | ||
+ | |||
+ | import | ||
+ | import random as rand | ||
+ | |||
+ | #### | ||
+ | |||
+ | def random_rgb(): | ||
+ | |||
+ | | ||
+ | |||
+ | #### | ||
+ | |||
+ | class PygView(object): | ||
+ | |||
+ | |||
+ | def __init__(self, | ||
+ | | ||
+ | and screen surface for dynamic drawing | ||
+ | """ | ||
+ | pyg.init() | ||
+ | pyg.display.set_caption(" | ||
+ | |||
+ | self.width = width | ||
+ | self.height = height | ||
+ | |||
+ | self.screen = pyg.display.set_mode((self.width, | ||
+ | self.background = pyg.Surface(self.screen.get_size()).convert() | ||
+ | # white blackground | ||
+ | self.background.fill((255, | ||
+ | |||
+ | self.act_surface = self.screen | ||
+ | self.act_rgb = 255, 0, 0 | ||
+ | |||
+ | |||
+ | def draw_static(self): | ||
+ | |||
+ | self.act_surface = self.background | ||
+ | |||
+ | |||
+ | def draw_dynamic(self): | ||
+ | |||
+ | self.act_surface = self.screen | ||
+ | |||
+ | |||
+ | def set_color(self, | ||
+ | |||
+ | self.act_rgb = rgb | ||
+ | |||
+ | |||
+ | def circle(self, | ||
+ | """ | ||
+ | """ | ||
+ | rad2 = 2 * radius | ||
+ | surface = pyg.Surface((rad2, | ||
+ | pyg.draw.circle(surface, | ||
+ | surface.set_colorkey((0, | ||
+ | self.act_surface.blit(surface.convert_alpha(), | ||
+ | |||
+ | |||
+ | def run(self, draw_dynamic): | ||
+ | """ | ||
+ | """ | ||
+ | running = True | ||
+ | while running: | ||
+ | for event in pyg.event.get(): | ||
+ | if event.type == pyg.QUIT: | ||
+ | running = False | ||
+ | elif event.type == pyg.KEYDOWN: | ||
+ | if event.key == pyg.K_ESCAPE: | ||
+ | running = False | ||
+ | |||
+ | draw_dynamic() | ||
+ | pyg.display.flip() | ||
+ | self.screen.blit(self.background, | ||
+ | |||
+ | pyg.quit() | ||
+ | |||
+ | #### | ||
+ | |||
+ | class Ball(object): | ||
+ | """ | ||
+ | (and other libs too, obviously...) | ||
+ | """ | ||
+ | def __init__(self, | ||
+ | |||
+ | self.x = x | ||
+ | self.y = y | ||
+ | self.radius = radius | ||
+ | self.act_radius = radius | ||
+ | self.speed_x = speed_x | ||
+ | self.speed_pulse = speed_pulse | ||
+ | self.color = color | ||
+ | self.width = width | ||
+ | self.shrinking = True | ||
+ | |||
+ | |||
+ | @property | ||
+ | def max_x(self): | ||
+ | |||
+ | return self.x + self.radius * 2 | ||
+ | |||
+ | |||
+ | def rel_move(self, | ||
+ | |||
+ | self.x += dx | ||
+ | self.y += dy | ||
+ | |||
+ | |||
+ | def pulse(self): | ||
+ | """ | ||
+ | """ | ||
+ | if not self.speed_pulse: | ||
+ | return | ||
+ | |||
+ | # balls are shrinking first | ||
+ | if self.shrinking: | ||
+ | if self.act_radius | ||
+ | | ||
+ | self.act_radius = max(self.act_radius, | ||
+ | else: | ||
+ | self.shrinking = False | ||
+ | else: | ||
+ | if self.act_radius | ||
+ | self.act_radius += self.speed_pulse | ||
+ | else: | ||
+ | self.shrinking = True | ||
+ | |||
+ | |||
+ | def draw(self, view): | ||
+ | """ | ||
+ | """ | ||
+ | if self.speed_pulse: | ||
+ | color = random_rgb() | ||
+ | else: | ||
+ | color = self.color | ||
+ | view.set_color(color) | ||
+ | view.circle(self.x, | ||
+ | |||
+ | #### | ||
+ | |||
+ | def action(balls, | ||
+ | """ | ||
+ | """ | ||
+ | # balls move to the right first | ||
+ | right_moving = [True] * len(balls) | ||
+ | |||
+ | def animate_balls(): | ||
+ | """ | ||
+ | """ | ||
+ | for i, ball in enumerate(balls): | ||
+ | if right_moving[i]: | ||
+ | if ball.max_x < width: | ||
+ | ball.rel_move(ball.speed_x, | ||
+ | else: | ||
+ | right_moving[i] = False | ||
+ | else: | ||
+ | if ball.x | ||
+ | ball.rel_move(-ball.speed_x, | ||
+ | else: | ||
+ | right_moving[i] = True | ||
+ | |||
+ | ball.pulse() | ||
+ | ball.draw(view) | ||
+ | |||
+ | return animate_balls | ||
+ | |||
+ | #### | ||
+ | |||
+ | def main(width): | ||
+ | """ | ||
+ | """ | ||
+ | view = PygView(width) | ||
+ | |||
+ | view.draw_static() | ||
+ | # args: x, y, radius, speed_x, speed_pulse, | ||
+ | # border_width <= radius ! | ||
+ | ball01 = Ball(50, 60, 50, 0, 0, (255, 255, 0)) | ||
+ | ball01.draw(view) | ||
+ | ball02 = Ball(250, 150, 190, 0, 0, (66, 1, 166)) | ||
+ | ball02.draw(view) | ||
+ | |||
+ | view.draw_dynamic() | ||
+ | ball1 = Ball(15, 130, 100, 1, 0, (255, 0, 0)) | ||
+ | ball2 = Ball(25, 200, 80, 2, 0, (0, 255, 155)) | ||
+ | ball3 = Ball(20, 220, 110, 1, 1, (100, 55, 155)) | ||
+ | ball4 = Ball(20, 400, 70, 3, 0, (250, 100, 255)) | ||
+ | ball5 = Ball(90, 390, 70, 0, 1, (250, 100, 255), 1) | ||
+ | |||
+ | loopfunc = action((ball1, | ||
+ | view.run(loopfunc) | ||
+ | |||
+ | #### | ||
+ | |||
+ | if __name__ == ' | ||
+ | |||
+ | main(900) | ||
+ | |||
+ | |||
+ | </code> | ||
^ [[: | ^ [[: | ||
====== Comment this Ptage ====== | ====== Comment this Ptage ====== | ||
- | ~~DISQUS~~ | + | |