Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to add points to your Python game

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly introduces "how to add score to your Python game". In daily operation, I believe many people have doubts about how to add score to your Python game. Xiaobian consulted all kinds of information and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubt of "how to add score to your Python game". Next, please follow the editor to study!

Show score in Pygame

Now that you have awards that can be collected by players, there is good reason to record scores so that your players can see how many awards they have collected. You can also track players' health so that they will have corresponding results when they are hit by the enemy.

You already have variables that track scores and health, but it all happens in the background. This article teaches you to display these statistics in a font of your choice on the game screen during the game.

Read the document

Most Python modules have documentation, and even those that do not have documentation can be minimized with the help of Python. The main page of Pygame links to its documents. However, Pygame is a large module with a lot of documentation, and its documentation is not written in the same easy-to-understand (and friendly, easy to explain, useful) narrative style as the articles on Opensource.com. They are technical documentation and list each class and function available in the module, the type of input required, and so on. If you are not used to reference code component descriptions, this can be overwhelming.

Before you worry about the library's documentation, the first thing to do is to think about what you are trying to achieve. In this case, you want to display the player's score and health on the screen.

After you determine the result you need, think about what components it needs. You can think about this in terms of variables and functions, or, if you haven't thought about it naturally, you can think about it in general. You may realize that you need some text to display a score, and you want Pygame to draw the text on the screen. If you think about it carefully, you may realize how different it is from rendering a player, reward, or platform on the screen.

Technically, you can use digital graphics and have Pygame display them. It's not the easiest way to achieve your goal, but if it's the only way you know, it's an effective way. However, if you refer to Pygame's documentation, you can see that one of the modules listed is font, which is how Pygame makes printed text on the screen as easy as typing text.

Decrypt technical documents

The font document page starts with pygame.font.init (), which lists the functions used to initialize the font module. It is called automatically by pygame.init (), and you have already called it in your code. Again, technically, you have reached a good enough point. Although you don't know how to do it yet, you know you can use the pygame.font function to print text on the screen.

However, if you read more, you will find a better way to print fonts here. The pygame.freetype module is described in the document as follows:

The pygame.freetype module is an alternative to the pygame.fontpygame module for loading and rendering fonts. It has all the functions of the original function, plus many new functions.

At the bottom of the pygame.freetype document page, there is some sample code:

Import pygameimport pygame.freetype

Your code should have been imported into Pygame, but please modify your import statement to include the Freetype module:

Import pygameimport sysimport osimport pygame.freetype uses fonts in Pygame

As you can see from the description of the font module, it is clear that Pygame uses a font (regardless of its default font provided by you or built into Pygame) to render fonts on the screen. Scroll through the pygame.freetype document to find the pygame.freetype.Font function:

Pygame.freetype.Font creates a new font instance from a supported font file. Font (file, size=0, font_index=0, resolution=0, ucs4=False)-> Font pygame.freetype.Font.name font names that conform to the rules. Pygame.freetype.Font.path font file path. Default point size used by pygame.freetype.Font.size in rendering

This describes how to build a font "object" in Pygame. It may not be natural for you to think of a simple object on the screen as a combination of code attributes, but it's very similar to the way you build hero and enemy elves. You need a font file, not an image file. After you have a font file, you can use the pygame.freetype.Font function in your code to create a font object, and then use that object to render the text on the screen.

Because not everyone in the world has exactly the same font on their computer, it's important to tie the font you choose to your game. To bundle fonts, first create a new directory in your game folder next to the file directory you created for the image. Call it fonts.

Even if your computer operating system ships with several fonts, it is illegal to give them to others. It may seem strange, but that's how the law works. If you want to ship a font with your game, you must find an open source or knowledge-sharing font that allows you to provide the font with the game.

Websites that specialize in free and legal fonts include:

Font Library

Font Squirrel

League of Moveable Type

When you find the font you like, download it. Extract the ZIP or TAR file and move the .ttf or .otf file to the fonts folder in your project directory.

You did not install fonts on your computer. You just put the font in the fonts folder of your game so that Pygame can use it. You can install the font on your computer if you want, but it's not necessary. It is important to put fonts in your game directory so that Pygame can "paint" fonts to the screen.

If the name of the font file is complex and contains spaces or special characters, you just need to rename it. The file name is completely arbitrary, and for you, the simpler the file name, the easier it is to type it into your code.

Now tell Pygame your font. You know from the document that when you at least provide a font file path to pygame.freetype.Font (the document clearly indicates that all remaining properties are optional), you will get a font object in the return:

Font (file, size=0, font_index=0, resolution=0, ucs4=False)-> Font

Create a new variable called myfont to act as your font in the game, and place the result of the Font function in this variable. Amazdoom.ttf fonts are used in this example, but you can use any font you want. Place these codes in your settings section:

Font_path = os.path.join (os.path.dirname (os.path.realpath (_ _ file__)), "fonts", "amazdoom.ttf") font_size = txmyfont = pygame.freetype.Font (font_path, font_size) displays text in Pygame

Now that you have created a font object, you need a function to draw the text you want to draw to the screen. This is the same principle as you draw the background and platform in your game.

First, create a function and use the myfont object to create some text, setting the color to some RGB value. This must be a global function; it does not belong to any specific class:

Def stats (score,health): myfont.render_to (world, (4,4), "Score:" + str (score), WHITE, None, size=64) myfont.render_to (world, (4,72), "Health:" + str (health), WHITE, None, size=64)

Of course, you already know by now that nothing will happen to your game if it is not in the main loop, so add a call to your stats function at the bottom of the file:

For e in enemy_list: e.move () stats (player.score,player.health) # draw text pygame.display.flip ()

Try your game.

When players collect rewards, the score goes up. Health drops when a player is hit by an enemy. Success!

Keeping score in Pygame

But there's a problem. When a player is hit by an enemy, his health will decline all the way, which is unfair. You just found a non-fatal mistake. The non-fatal errors are that these minor problems in the application do not prevent the application from starting or even cause it to stop working, but they are either meaningless or annoy to the user. Here is how to solve this problem.

Repair health count

The problem with the current health system is that every tick of the Pygame clock decreases health when the enemy touches the player. This means that a slow-moving enemy may reduce a player's health to-200 in an encounter, which is unfair. Of course, you can give your player an initial health score of 10000 without having to worry about it; it works, and probably no one will notice. But there's a better way.

Currently, your code detects a collision between a player and an enemy. The fix to the health problem is to detect two separate events: when the player and the enemy collide, and when they stop colliding after they collide.

First, in your player class, create a variable to represent the collision between the player and the enemy:

Self.frame = 0 self.health = 10 self.damage = 0

In the update function of your Player class, remove this block of code:

For enemy in enemy_hit_list: self.health-= 1 # print (self.health)

And in its position, as long as the player is not currently hit, check the collision:

If self.damage = = 0: for enemy in enemy_hit_list: if not self.rect.contains (enemy): self.damage = self.rect.colliderect (enemy)

You may see similarities between the statement blocks you deleted and the statement blocks you just added. They're all doing the same thing, but the new code is more complex. Most importantly, the new code runs only if the player is not currently hit. This means that when a player collides with an enemy, the code runs once instead of colliding all the time.

The new code uses two new Pygame functions. The self.rect.contains function checks whether an enemy is currently in the player's bounding box, and when it is true, self.rect.colliderect sets your new self.damage variable to 1, no matter how many times it is true.

Now, even if you are hit by an enemy for 3 seconds, it is still considered a hit for Pygame.

I discovered these functions by reading through the Pygame documentation. You don't have to read all the documents at once, and you don't have to read every word of every function. However, it is important to spend time documenting the new library or module you are using; otherwise, you are most likely reinventing the wheel. Don't spend an afternoon trying to modify and splice a solution to something that has been solved by the framework you are using. Read the documentation, learn about functions, and benefit from other people's work!

Finally, add another code statement block to detect when the player is no longer in contact with the enemy. Then it was not until then that one health was reduced from the player.

If self.damage = = 1: idx = self.rect.collidelist (enemy_hit_list) if idx =-1: self.damage = 0 # set damage back to 0 self.health-= 1 # subtract 1 hp

Note that this new code is triggered only when the player is hit. This means that the code will not run when your players are exploring or collecting rewards in your game world. It runs only when the self.damage variable is activated.

When the code runs, it uses self.rect.collidelist to see if the player is still in contact with an enemy in your enemy list (collidelist returns-1 when it does not detect a collision). When it doesn't touch the enemy, it's time to deal with self.damage: invalidate it by setting the self.damage variable back to 0, and reduce its health a little bit.

Now try your game.

Score response

Now, you have a way to let your players know their scores and health, and when your players reach certain milestones, you can make sure that certain events occur. For example, there may be a special incentive program to restore some health. Maybe a player who reaches 0 health has to start again from the starting position of a level.

You can check these events in your code and manipulate your game world accordingly. You already know what to do, so browse the documentation to find new techniques and try them independently.

Here is all the code so far:

#! / 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# add jumping# add scrolling# add loot# add score # GNU All-Permissive License# Copying and distribution of this 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 pygameimport sysimport osimport pygame.freetype''Objects''' class Platform (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 class Player (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.damage = 0 self.collide_delta = 0 self.jump_delta = 6 self.score = 1 self.images = [] for i in range (1): img = pygame.image.load ('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 jump (self Platform_list): self.jump_delta = 0 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 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 += 1 if self.frame >

Ani*3: self.frame = 0 self.image = self.images [self.frame//ani] # moving right if self.movex > 0: self.frame + = 1 if 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) if self.damage = = 0: for enemy in enemy_hit_list: if not self.rect.contains (enemy): self.damage = self.rect.colliderect (enemy) if self.damage = = 1: idx = self.rect.collidelist (enemy_hit_list) if idx =-1: Self.damage = 0 # set damage back to 0 self.health-= 1 # subtract 1 hp loot_hit_list = pygame.sprite.spritecollide (self Loot_list, False) for loot in loot_hit_list: loot_list.remove (loot) self.score + = 1 print (self.score) plat_hit_list = pygame.sprite.spritecollide (self, plat_list) False) for pin plat_hit_list: self.collide_delta = 0 # stop jumping self.movey = 0 if self.rect.y > p.rect.y: self.rect.y = p.rect.y+ty else: self.rect.y = p.rect.y-ty ground_hit_list = pygame.sprite.spritecollide (self Ground_list, False) for g in ground_hit_list: self.movey = 0 self.rect.y = worldy-ty-ty self.collide_delta = 0 # stop jumping if self.rect.y > g.rect.y: self.health-= 1 print (self.health) if self.collide_delta

< 6 and self.jump_delta < 6: self.jump_delta = 6*2 self.movey -= 33 # how high to jump self.collide_delta += 6 self.jump_delta += 6 class Enemy(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.movey = 0 #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 = 8 self.movey += 3.2 if self.counter >

= 0 and self.counter = distance and self.counter = worldy-ty-ty: self.rect.y + = self.movey plat_hit_list = pygame.sprite.spritecollide (self, plat_list False) for p in plat_hit_list: self.movey = 0 if self.rect.y > p.rect.y: self.rect.y = p.rect.y+ty else: self.rect.y = p.rect.y-ty ground_hit_list = pygame.sprite.spritecollide (self, ground_list False) for g in ground_hit_list: self.rect.y = worldy-ty-ty class Level (): 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,tx) Ty): if lvl = = 1: loot_list = pygame.sprite.Group () loot = Platform (200recorder TX loot_list.add, 'loot_1.png') loot_list.add (loot) if lvl = = 2: print (lvl) return loot_list def ground (lvl,gloc,tx Ty): ground_list = pygame.sprite.Group () iTun0 if lvl = = 1: while I < len (gloc): ground = Platform (gloci [I], worldy-ty,tx,ty 'ground.png') ground_list.add (ground) i=i+1 if lvl = 2: print ("Level" + str (lvl)) return ground_list def platform (lvl,tx,ty): plat_list = pygame.sprite.Group () ploc = [] iTun0 if lvl = = 1: ploc.append ((20) Worldy-ty-128,3)) ploc.append ((300) ploc.append ((500) len (ploc): juni0 while j

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report