Upload
tanwir-zaman
View
44
Download
2
Tags:
Embed Size (px)
DESCRIPTION
Citation preview
Python & Perl
Lecture 09
Department of Computer ScienceUtah State University
Outline● PyGame● Sprite Movements● Build a simple game
Games
● Games are one of the most applicative areas of programming.
● To write even the simplest games, you have to get into graphics, math, physics and even AI.
● It’s a great and fun way to practice programming.
Creeps
A complete simulation of creeps, round creatures that move around the screen, bouncing off walls and changing their direction from time to time.
Goals
● We want to have creeps moving around the screen● The amount of creeps and their appearance should be
easily configurable● The creeps will bounce off walls correctly● To make things more interesting, the creeps will exhibit
semi-random behavior
So what is a creep ?
● A creep is a small image that will be moved around the screen and rotated using Pygame’s capabilities
● In gaming terminology they are known as sprites● We limit the rotations to quantas of 45 degrees
(meaning that creeps will move up, down, left, right or in 4 diagonals)
How do creeps "move" ?
● Movement is an illusion. Nothing really moves on a computer screen.
● Rather, the program displays a sequence of images with small displacements fast enough for the human eye to perceive movement.
● The rule of thumb is that anything with 30 updates per second or faster is good enough and looks smooth to the average person.
Game Loop
The game loop
How often does this loop run ?
● This is decided by the call to clock.tick. ● clock is a pygame.time.Clock object. ● The call to tick basically says this: sleep until the next
1/50 second boundary, at most. This limits the game speed to 50 FPS, which is a good thing, because we want the game to be smooth on one hand, and not eat up most of the CPU on the other hand.
What comes before the loop
Creep class
Creep constructor
● The Creep is provided with a random image from the list of images (choice is a function from Python’s standard random module)
● It is set in a random position on the screen (randint is also from random)
● A random direction (more about the direction later)● The speed is set to 0.1 px/ms (0.1 pixels per
millisecond), or 100 pixels per second
Vectors and directions
● Vectors are the chief mathematical tool for making computations related to movement on the screen
● We’ll use vectors for two things: Position
Velocity
Vectors and directions
Vectors and directions
● A point on the XY plane can be represented by a 2D vector.
● The difference between two vectors is the velocity (displacement) vector.
● In other words, adding the velocity vector to the original position vector yields the new position.
Normalized Vectors● In almost all graphical drawing interfaces, the top-left
corner is (0, 0), X increases to the right, and Y increases to downwards. In other words, the screen drawing XY plane is:
Implementing vectors
● Surprisingly, Pygame doesn’t have a "standard" vector implementation shipping with it.
● So game writers have to either roll their own or find vector modules online.
● We will use the vec2d.py file, a 2D vector implementation the Pygame Wiki.
Updating the creep
● The most interesting function of this demo is the update method of Creep
def update(self, time_passed)● This method is called periodically by the main loop and
is passed the amount of time passed (in milliseconds) since the previous call.
Updating the creep
Rotating the creeps
● transform.rotate rotates a given surface counterclockwise by the provided angle.
self.image = pygame.transform.rotate
(self.base_image, -self.direction.angle)● We give it a negation of the angle because of the
inverted "screen XY plane"
Rotating the creeps
● Suppose our rotation direction is 45 degrees (that is, south-east in our screen coordinates)
● If we give 45 degrees to rotate, it will make the creep point north-east (as its rotation is counterclockwise). So to perform the correct rotation, we have to negate the angle.
Update continued
● Next in update method we have
Displacement
displacement = vec2d(self.direction.x * self.speed * time_passed,self.direction.y * self.speed * time_passed)
● self.direction is a normalized vector that tells us where the creep points to
● The displacement is computed from the basic rule of motion that distance equals speed multiplied by time
Blitting● Blitting is the game programmers’ jargon for transferring
an image (or a pattern) onto a drawable surface. In Pygame this is implemented with the blit function
Blitting
● Blitting, like many other things in Pygame, uses the versatile pygame.Rect class
● The call to blit accepts an image (a surface, actually) and a rectangle that specifies where this image will be blitted to the surface on which blit is invoked
● We provide the drawing position as the creep’s current position (self.pos) but with a small adjustment
Blitting
● When images are rotated in Pygame, their size increases.
● Since the image is square, Pygame has to include all of its information in the rotated image, so the rotated image has to grow in size. This only happens for rotations that are not multiples of 90 degrees
● Whenever a creep turns, its image size changes. Without a special adjustment, the creep will shift with each turn and the animation won’t be smooth and pretty.
Blit adjustment
● We center the creep when we draw it● The draw position is computed to be the center of the
creep’s image. Even when the image rotates and grows, its center stays in the same place, so there will be no noticeable shift in the creep this way.
Bouncing off walls
Bouncing off walls
● First, the screen boundary itself is computed, by taking the rectangle representing the screen and adjusting it to the image size
● Then, for each of the 4 walls we compute whether the creep collides with it, and if it does, the creep’s direction is inverted in the axis perpendicular to the wall
Change directions
● if self.pos.x < bounds_rect.left:
self.pos.x = bounds_rect.left
self.direction.x *= -1
This is for the bounce off the left wall. The creeps always arrives to it from the right, so when we negate the X component of its direction vector while keeping the Y component intact, it will start moving to the right but with the same vertical direction.
Reading & References● http://www.pygame.org/● http://eli.thegreenplace.net/2008/12/13/writing-a-game-in-
python-with-pygame-part-i/