Python “貪吃蛇”游戲,在不斷改進中學習pygame編程

1ae28d15992f405bb7fd51daa60c3dc2.gif

目錄

前言

改進過程一

增加提示信息

原版幫助摘要

pygame.draw

pygame.font

class Rect

class Surface

改進過程二

增加顯示得分

改進過程三

增加背景景樂

增加提示音效

音樂切換

靜音切換

mixer.music.play 注意事項

原版幫助摘要

pygame.mixer

pygame.mixer.Sound

小結

pygame編程框架


?

前言

在上一篇博文里,從訊飛星火中獲取到游戲“貪吃蛇”的代碼,運行效果如上圖。代碼并不完整,當蛇死了就退出游戲,不能多次玩這個游戲。

前文鏈接:

訊飛星火、文心一言和通義千問同時編“貪吃蛇”游戲,誰會勝出?

代碼如下:

import pygame
import sys
import random# 定義顏色
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED  = (255, 0, 0)
GREY = (211, 211, 211)  # 淡灰色def init():global screen, screen_sizeglobal snake_pos, food_pos, snake_speed# 初始化pygamepygame.init()# 設置屏幕大小screen_size = (640, 480)screen = pygame.display.set_mode(screen_size)# 設置游戲標題pygame.display.set_caption("貪吃蛇")# 蛇的初始位置snake_pos = [[100, 100], [80, 100], [60, 100]]# 食物的初始位置food_pos = [300, 300]# 蛇的初始速度snake_speed = [20, 0]def repaint():# 繪制游戲界面screen.fill(WHITE)# 定義線段的端點坐標x,y = (-1,640,640,-1)*16, []for i in range(36):for _ in range(2):y.append(19+i*20)# 使用pygame.draw.lines()函數繪制線段points = list(zip(x,y))pygame.draw.lines(screen, GREY, False, points, 1) # 線寬為1points = list(zip(y,x))pygame.draw.lines(screen, GREY, False, points, 1)   # 重畫蛇和食物for pos in snake_pos:pygame.draw.rect(screen, GREEN, pygame.Rect(pos[0], pos[1], 20, 20))pygame.draw.rect(screen, RED, pygame.Rect(food_pos[0], food_pos[1], 20, 20))pygame.display.flip()def game_quit():pygame.quit()sys.exit()def main():global screen, screen_sizeglobal snake_pos, food_pos, snake_speed# 主循環while True:# 處理游戲事件for event in pygame.event.get():if event.type == pygame.QUIT:game_quit()elif event.type == pygame.KEYDOWN:if event.key == pygame.K_UP:snake_speed = [0, -20]elif event.key == pygame.K_DOWN:snake_speed = [0, 20]elif event.key == pygame.K_LEFT:snake_speed = [-20, 0]elif event.key == pygame.K_RIGHT:snake_speed = [20, 0]# 更新蛇的位置snake_pos.insert(0, [snake_pos[0][0] + snake_speed[0], snake_pos[0][1] + snake_speed[1]])# 檢查蛇頭是否碰到食物if snake_pos[0] == food_pos:food_pos = [random.randrange(1, screen_size[0] // 20) * 20, random.randrange(1, screen_size[1] // 20) * 20]else:snake_pos.pop()# 檢查蛇頭是否碰到墻壁或者蛇身if snake_pos[0][0] < 0 or snake_pos[0][0] >= screen_size[0] or snake_pos[0][1] < 0 or snake_pos[0][1] >= screen_size[1] or snake_pos[0] in snake_pos[1:]:game_quit()'''此處可增加與用戶的交互,如:if askyesno('title','again?'):init() # Yes to Play againelse:game_quit() # No to Exit'''# 重畫界面及蛇和食物repaint()# 控制游戲速度pygame.time.Clock().tick(10)if __name__ == "__main__":init()main()

改進過程一

增加提示信息

之前沒有仔細學過pygame的編程,剛好拿這例程練練手,在不斷改進中學習pygame編程。

原代碼一執行,蛇就開始游動了,就從這里入手。開始前,增加顯示“按任意鍵開始...”的提示。

蛇死后,提醒是否重來?Yes to play again, No to quit game.

同時,在游戲中允許按ESC鍵暫停游戲,再按一次繼續。

由于沒查到 pygame 有彈出信息窗口的方法(函數),于是用了DOS時代顯示信息窗口的辦法,畫多個矩形窗口來模擬窗口,最后在矩形框上寫上提示文字。代碼如下:

def show_msg(msg, color = BLUE):
? ? x = screen.get_rect().centerx
? ? y = screen.get_rect().centery - 50
? ? font = pygame.font.Font(None, 36)
? ? text = font.render(msg, True, color)
? ? text_rect = text.get_rect()
? ? text_rect.centerx = x
? ? text_rect.centery = y
? ? rectangle1 = pygame.Rect(x-155, y-25, 320, 60)
? ? rectangle2 = pygame.Rect(x-160, y-30, 320, 60)
? ? pygame.draw.rect(screen, DARK, rectangle1)
? ? pygame.draw.rect(screen, GREY, rectangle2)
? ? pygame.draw.rect(screen, BLACK, rectangle2, 2) # 邊框寬為2
? ? screen.blit(text, text_rect)
? ? pygame.display.flip()


原版幫助摘要

pygame.draw

NAME
? ? pygame.draw - pygame module for drawing shapes

FUNCTIONS
? ? aaline(...)
? ? ? ? aaline(surface, color, start_pos, end_pos) -> Rect
? ? ? ? aaline(surface, color, start_pos, end_pos, blend=1) -> Rect
? ? ? ? draw a straight antialiased line
? ??
? ? aalines(...)
? ? ? ? aalines(surface, color, closed, points) -> Rect
? ? ? ? aalines(surface, color, closed, points, blend=1) -> Rect
? ? ? ? draw multiple contiguous straight antialiased line segments
? ??
? ? arc(...)
? ? ? ? arc(surface, color, rect, start_angle, stop_angle) -> Rect
? ? ? ? arc(surface, color, rect, start_angle, stop_angle, width=1) -> Rect
? ? ? ? draw an elliptical arc
? ??
? ? circle(...)
? ? ? ? circle(surface, color, center, radius) -> Rect
? ? ? ? circle(surface, color, center, radius, width=0, draw_top_right=None, draw_top_left=None, draw_bottom_left=None, draw_bottom_right=None) -> Rect
? ? ? ? draw a circle
? ??
? ? ellipse(...)
? ? ? ? ellipse(surface, color, rect) -> Rect
? ? ? ? ellipse(surface, color, rect, width=0) -> Rect
? ? ? ? draw an ellipse
? ??
? ? line(...)
? ? ? ? line(surface, color, start_pos, end_pos) -> Rect
? ? ? ? line(surface, color, start_pos, end_pos, width=1) -> Rect
? ? ? ? draw a straight line
? ??
? ? lines(...)
? ? ? ? lines(surface, color, closed, points) -> Rect
? ? ? ? lines(surface, color, closed, points, width=1) -> Rect
? ? ? ? draw multiple contiguous straight line segments
? ??
? ? polygon(...)
? ? ? ? polygon(surface, color, points) -> Rect
? ? ? ? polygon(surface, color, points, width=0) -> Rect
? ? ? ? draw a polygon
? ??
? ? rect(...)
? ? ? ? rect(surface, color, rect) -> Rect
? ? ? ? rect(surface, color, rect, width=0, border_radius=0, border_top_left_radius=-1, border_top_right_radius=-1, border_bottom_left_radius=-1, border_bottom_right_radius=-1) -> Rect
? ? ? ? draw a rectangle


pygame.font

NAME
? ? pygame.font - pygame module for loading and rendering fonts

CLASSES
? ? builtins.object
? ? ? ? Font
? ??
? ? class Font(builtins.object)
? ? ?| ?Font(file_path=None, size=12) -> Font
? ? ?| ?Font(file_path, size) -> Font
? ? ?| ?Font(pathlib.Path, size) -> Font
? ? ?| ?Font(object, size) -> Font
? ? ?| ?create a new Font object from a file
? ? ?| ?
? ? ?| ?Methods defined here:
? ? ?| ?
? ? ?| ?__init__(self, /, *args, **kwargs)
? ? ?| ? ? ?Initialize self. ?See help(type(self)) for accurate signature.
? ? ?| ?
? ? ?| ?get_ascent(...)
? ? ?| ? ? ?get_ascent() -> int
? ? ?| ? ? ?get the ascent of the font
? ? ?| ?
? ? ?| ?get_bold(...)
? ? ?| ? ? ?get_bold() -> bool
? ? ?| ? ? ?check if text will be rendered bold
? ? ?| ?
? ? ?| ?get_descent(...)
? ? ?| ? ? ?get_descent() -> int
? ? ?| ? ? ?get the descent of the font
? ? ?| ?
? ? ?| ?get_height(...)
? ? ?| ? ? ?get_height() -> int
? ? ?| ? ? ?get the height of the font
? ? ?| ?
? ? ?| ?get_italic(...)
? ? ?| ? ? ?get_italic() -> bool
? ? ?| ? ? ?check if the text will be rendered italic
? ? ?| ?
? ? ?| ?get_linesize(...)
? ? ?| ? ? ?get_linesize() -> int
? ? ?| ? ? ?get the line space of the font text
? ? ?| ?
? ? ?| ?get_strikethrough(...)
? ? ?| ? ? ?get_strikethrough() -> bool
? ? ?| ? ? ?check if text will be rendered with a strikethrough
? ? ?| ?
? ? ?| ?get_underline(...)
? ? ?| ? ? ?get_underline() -> bool
? ? ?| ? ? ?check if text will be rendered with an underline
? ? ?| ?
? ? ?| ?metrics(...)
? ? ?| ? ? ?metrics(text) -> list
? ? ?| ? ? ?gets the metrics for each character in the passed string
? ? ?| ?
? ? ?| ?render(...)
? ? ?| ? ? ?render(text, antialias, color, background=None) -> Surface
? ? ?| ? ? ?draw text on a new Surface
? ? ?| ?
? ? ?| ?set_bold(...)
? ? ?| ? ? ?set_bold(bool) -> None
? ? ?| ? ? ?enable fake rendering of bold text
? ? ?| ?
? ? ?| ?set_italic(...)
? ? ?| ? ? ?set_italic(bool) -> None
? ? ?| ? ? ?enable fake rendering of italic text
? ? ?| ?
? ? ?| ?set_script(...)
? ? ?| ? ? ?set_script(str) -> None
? ? ?| ? ? ?set the script code for text shaping
? ? ?| ?
? ? ?| ?set_strikethrough(...)
? ? ?| ? ? ?set_strikethrough(bool) -> None
? ? ?| ? ? ?control if text is rendered with a strikethrough
? ? ?| ?
? ? ?| ?set_underline(...)
? ? ?| ? ? ?set_underline(bool) -> None
? ? ?| ? ? ?control if text is rendered with an underline
? ? ?| ?
? ? ?| ?size(...)
? ? ?| ? ? ?size(text) -> (width, height)
? ? ?| ? ? ?determine the amount of space needed to render text
? ? ?| ?
? ? ?| ?----------------------------------------------------------------------
? ? ?| ?Data descriptors defined here:
? ? ?| ?
? ? ?| ?bold
? ? ?| ? ? ?bold -> bool
? ? ?| ? ? ?Gets or sets whether the font should be rendered in (faked) bold.
? ? ?| ?
? ? ?| ?italic
? ? ?| ? ? ?italic -> bool
? ? ?| ? ? ?Gets or sets whether the font should be rendered in (faked) italics.
? ? ?| ?
? ? ?| ?strikethrough
? ? ?| ? ? ?strikethrough -> bool
? ? ?| ? ? ?Gets or sets whether the font should be rendered with a strikethrough.
? ? ?| ?
? ? ?| ?underline
? ? ?| ? ? ?underline -> bool
? ? ?| ? ? ?Gets or sets whether the font should be rendered with an underline.


class Rect

Help on class Rect in module pygame.rect:

class Rect(builtins.object)
?| ?Rect(left, top, width, height) -> Rect
?| ?Rect((left, top), (width, height)) -> Rect
?| ?Rect(object) -> Rect
?| ?pygame object for storing rectangular coordinates
?| ?
?| ?Methods defined here:
?| ?
?| ?clamp(...)
?| ? ? ?clamp(Rect) -> Rect
?| ? ? ?moves the rectangle inside another
?| ?
?| ?clamp_ip(...)
?| ? ? ?clamp_ip(Rect) -> None
?| ? ? ?moves the rectangle inside another, in place
?| ?
?| ?clip(...)
?| ? ? ?clip(Rect) -> Rect
?| ? ? ?crops a rectangle inside another
?| ?
?| ?clipline(...)
?| ? ? ?clipline(x1, y1, x2, y2) -> ((cx1, cy1), (cx2, cy2))
?| ? ? ?clipline(x1, y1, x2, y2) -> ()
?| ? ? ?clipline((x1, y1), (x2, y2)) -> ((cx1, cy1), (cx2, cy2))
?| ? ? ?clipline((x1, y1), (x2, y2)) -> ()
?| ? ? ?clipline((x1, y1, x2, y2)) -> ((cx1, cy1), (cx2, cy2))
?| ? ? ?clipline((x1, y1, x2, y2)) -> ()
?| ? ? ?clipline(((x1, y1), (x2, y2))) -> ((cx1, cy1), (cx2, cy2))
?| ? ? ?clipline(((x1, y1), (x2, y2))) -> ()
?| ? ? ?crops a line inside a rectangle
?| ?
?| ?collidedict(...)
?| ? ? ?collidedict(dict) -> (key, value)
?| ? ? ?collidedict(dict) -> None
?| ? ? ?collidedict(dict, use_values=0) -> (key, value)
?| ? ? ?collidedict(dict, use_values=0) -> None
?| ? ? ?test if one rectangle in a dictionary intersects
?| ?
?| ?collidedictall(...)
?| ? ? ?collidedictall(dict) -> [(key, value), ...]
?| ? ? ?collidedictall(dict, use_values=0) -> [(key, value), ...]
?| ? ? ?test if all rectangles in a dictionary intersect
?| ?
?| ?collidelist(...)
?| ? ? ?collidelist(list) -> index
?| ? ? ?test if one rectangle in a list intersects
?| ?
?| ?collidelistall(...)
?| ? ? ?collidelistall(list) -> indices
?| ? ? ?test if all rectangles in a list intersect
?| ?
?| ?collideobjects(...)
?| ? ? ?collideobjects(rect_list) -> object
?| ? ? ?collideobjects(obj_list, key=func) -> object
?| ? ? ?test if any object in a list intersects
?| ?
?| ?collideobjectsall(...)
?| ? ? ?collideobjectsall(rect_list) -> objects
?| ? ? ?collideobjectsall(obj_list, key=func) -> objects
?| ? ? ?test if all objects in a list intersect
?| ?
?| ?collidepoint(...)
?| ? ? ?collidepoint(x, y) -> bool
?| ? ? ?collidepoint((x,y)) -> bool
?| ? ? ?test if a point is inside a rectangle
?| ?
?| ?colliderect(...)
?| ? ? ?colliderect(Rect) -> bool
?| ? ? ?test if two rectangles overlap
?| ?
?| ?contains(...)
?| ? ? ?contains(Rect) -> bool
?| ? ? ?test if one rectangle is inside another
?| ?
?| ?copy(...)
?| ? ? ?copy() -> Rect
?| ? ? ?copy the rectangle
?| ?
?| ?fit(...)
?| ? ? ?fit(Rect) -> Rect
?| ? ? ?resize and move a rectangle with aspect ratio
?| ?
?| ?inflate(...)
?| ? ? ?inflate(x, y) -> Rect
?| ? ? ?grow or shrink the rectangle size
?| ?
?| ?inflate_ip(...)
?| ? ? ?inflate_ip(x, y) -> None
?| ? ? ?grow or shrink the rectangle size, in place
?| ?
?| ?move(...)
?| ? ? ?move(x, y) -> Rect
?| ? ? ?moves the rectangle
?| ?
?| ?move_ip(...)
?| ? ? ?move_ip(x, y) -> None
?| ? ? ?moves the rectangle, in place
?| ?
?| ?normalize(...)
?| ? ? ?normalize() -> None
?| ? ? ?correct negative sizes
?| ?
?| ?scale_by(...)
?| ? ? ?scale_by(scalar) -> Rect
?| ? ? ?scale_by(scalex, scaley) -> Rect
?| ? ? ?scale the rectangle by given a multiplier
?| ?
?| ?scale_by_ip(...)
?| ? ? ?scale_by_ip(scalar) -> None
?| ? ? ?scale_by_ip(scalex, scaley) -> None
?| ? ? ?grow or shrink the rectangle size, in place
?| ?
?| ?union(...)
?| ? ? ?union(Rect) -> Rect
?| ? ? ?joins two rectangles into one
?| ?
?| ?union_ip(...)
?| ? ? ?union_ip(Rect) -> None
?| ? ? ?joins two rectangles into one, in place
?| ?
?| ?unionall(...)
?| ? ? ?unionall(Rect_sequence) -> Rect
?| ? ? ?the union of many rectangles
?| ?
?| ?unionall_ip(...)
?| ? ? ?unionall_ip(Rect_sequence) -> None
?| ? ? ?the union of many rectangles, in place
?| ?
?| ?update(...)
?| ? ? ?update(left, top, width, height) -> None
?| ? ? ?update((left, top), (width, height)) -> None
?| ? ? ?update(object) -> None
?| ? ? ?sets the position and size of the rectangle


class Surface

class Surface(builtins.object)
?| ?Surface((width, height), flags=0, depth=0, masks=None) -> Surface
?| ?Surface((width, height), flags=0, Surface) -> Surface
?| ?pygame object for representing images
?| ?
?| ?Methods defined here:
?| ?
?| ?blit(...)
?| ? ? ?blit(source, dest, area=None, special_flags=0) -> Rect
?| ? ? ?draw one image onto another
?| ?
?| ?blits(...)
?| ? ? ?blits(blit_sequence=((source, dest), ...), doreturn=1) -> [Rect, ...] or None
?| ? ? ?blits(((source, dest, area), ...)) -> [Rect, ...]
?| ? ? ?blits(((source, dest, area, special_flags), ...)) -> [Rect, ...]
?| ? ? ?draw many images onto another
?| ?
?| ?convert(...)
?| ? ? ?convert(Surface=None) -> Surface
?| ? ? ?convert(depth, flags=0) -> Surface
?| ? ? ?convert(masks, flags=0) -> Surface
?| ? ? ?change the pixel format of an image
?| ?
?| ?convert_alpha(...)
?| ? ? ?convert_alpha(Surface) -> Surface
?| ? ? ?convert_alpha() -> Surface
?| ? ? ?change the pixel format of an image including per pixel alphas
?| ?
?| ?copy(...)
?| ? ? ?copy() -> Surface
?| ? ? ?create a new copy of a Surface
?| ?
?| ?fill(...)
?| ? ? ?fill(color, rect=None, special_flags=0) -> Rect
?| ? ? ?fill Surface with a solid color
?| ?
?| ?get_abs_offset(...)
?| ? ? ?get_abs_offset() -> (x, y)
?| ? ? ?find the absolute position of a child subsurface inside its top level parent
?| ?
?| ?get_abs_parent(...)
?| ? ? ?get_abs_parent() -> Surface
?| ? ? ?find the top level parent of a subsurface
?| ?
?| ?get_alpha(...)
?| ? ? ?get_alpha() -> int_value
?| ? ? ?get the current Surface transparency value
?| ?
?| ?get_at(...)
?| ? ? ?get_at((x, y)) -> Color
?| ? ? ?get the color value at a single pixel
?| ?
?| ?get_at_mapped(...)
?| ? ? ?get_at_mapped((x, y)) -> Color
?| ? ? ?get the mapped color value at a single pixel
?| ?
?| ?get_bitsize(...)
?| ? ? ?get_bitsize() -> int
?| ? ? ?get the bit depth of the Surface pixel format
?| ?
?| ?get_blendmode(...)
?| ? ? ?Return the surface's SDL 2 blend mode
?| ?
?| ?get_bounding_rect(...)
?| ? ? ?get_bounding_rect(min_alpha = 1) -> Rect
?| ? ? ?find the smallest rect containing data
?| ?
?| ?get_buffer(...)
?| ? ? ?get_buffer() -> BufferProxy
?| ? ? ?acquires a buffer object for the pixels of the Surface.
?| ?
?| ?get_bytesize(...)
?| ? ? ?get_bytesize() -> int
?| ? ? ?get the bytes used per Surface pixel
?| ?
?| ?get_clip(...)
?| ? ? ?get_clip() -> Rect
?| ? ? ?get the current clipping area of the Surface
?| ?
?| ?get_colorkey(...)
?| ? ? ?get_colorkey() -> RGB or None
?| ? ? ?Get the current transparent colorkey
?| ?
?| ?get_flags(...)
?| ? ? ?get_flags() -> int
?| ? ? ?get the additional flags used for the Surface
?| ?
?| ?get_height(...)
?| ? ? ?get_height() -> height
?| ? ? ?get the height of the Surface
?| ?
?| ?get_locked(...)
?| ? ? ?get_locked() -> bool
?| ? ? ?test if the Surface is current locked
?| ?
?| ?get_locks(...)
?| ? ? ?get_locks() -> tuple
?| ? ? ?Gets the locks for the Surface
?| ?
?| ?get_losses(...)
?| ? ? ?get_losses() -> (R, G, B, A)
?| ? ? ?the significant bits used to convert between a color and a mapped integer
?| ?
?| ?get_masks(...)
?| ? ? ?get_masks() -> (R, G, B, A)
?| ? ? ?the bitmasks needed to convert between a color and a mapped integer
?| ?
?| ?get_offset(...)
?| ? ? ?get_offset() -> (x, y)
?| ? ? ?find the position of a child subsurface inside a parent
?| ?
?| ?get_palette(...)
?| ? ? ?get_palette() -> [RGB, RGB, RGB, ...]
?| ? ? ?get the color index palette for an 8-bit Surface
?| ?
?| ?get_palette_at(...)
?| ? ? ?get_palette_at(index) -> RGB
?| ? ? ?get the color for a single entry in a palette
?| ?
?| ?get_parent(...)
?| ? ? ?get_parent() -> Surface
?| ? ? ?find the parent of a subsurface
?| ?
?| ?get_pitch(...)
?| ? ? ?get_pitch() -> int
?| ? ? ?get the number of bytes used per Surface row
?| ?
?| ?get_rect(...)
?| ? ? ?get_rect(**kwargs) -> Rect
?| ? ? ?get the rectangular area of the Surface
?| ?
?| ?get_shifts(...)
?| ? ? ?get_shifts() -> (R, G, B, A)
?| ? ? ?the bit shifts needed to convert between a color and a mapped integer
?| ?
?| ?get_size(...)
?| ? ? ?get_size() -> (width, height)
?| ? ? ?get the dimensions of the Surface
?| ?
?| ?get_view(...)
?| ? ? ?get_view(<kind>='2') -> BufferProxy
?| ? ? ?return a buffer view of the Surface's pixels.
?| ?
?| ?get_width(...)
?| ? ? ?get_width() -> width
?| ? ? ?get the width of the Surface
?| ?
?| ?lock(...)
?| ? ? ?lock() -> None
?| ? ? ?lock the Surface memory for pixel access
?| ?
?| ?map_rgb(...)
?| ? ? ?map_rgb(Color) -> mapped_int
?| ? ? ?convert a color into a mapped color value
?| ?
?| ?mustlock(...)
?| ? ? ?mustlock() -> bool
?| ? ? ?test if the Surface requires locking
?| ?
?| ?premul_alpha(...)
?| ? ? ?premul_alpha() -> Surface
?| ? ? ?returns a copy of the surface with the RGB channels pre-multiplied by the alpha channel.
?| ?
?| ?scroll(...)
?| ? ? ?scroll(dx=0, dy=0) -> None
?| ? ? ?Shift the surface image in place
?| ?
?| ?set_alpha(...)
?| ? ? ?set_alpha(value, flags=0) -> None
?| ? ? ?set_alpha(None) -> None
?| ? ? ?set the alpha value for the full Surface image
?| ?
?| ?set_at(...)
?| ? ? ?set_at((x, y), Color) -> None
?| ? ? ?set the color value for a single pixel
?| ?
?| ?set_clip(...)
?| ? ? ?set_clip(rect) -> None
?| ? ? ?set_clip(None) -> None
?| ? ? ?set the current clipping area of the Surface
?| ?
?| ?set_colorkey(...)
?| ? ? ?set_colorkey(Color, flags=0) -> None
?| ? ? ?set_colorkey(None) -> None
?| ? ? ?Set the transparent colorkey
?| ?
?| ?set_masks(...)
?| ? ? ?set_masks((r,g,b,a)) -> None
?| ? ? ?set the bitmasks needed to convert between a color and a mapped integer
?| ?
?| ?set_palette(...)
?| ? ? ?set_palette([RGB, RGB, RGB, ...]) -> None
?| ? ? ?set the color palette for an 8-bit Surface
?| ?
?| ?set_palette_at(...)
?| ? ? ?set_palette_at(index, RGB) -> None
?| ? ? ?set the color for a single index in an 8-bit Surface palette
?| ?
?| ?set_shifts(...)
?| ? ? ?set_shifts((r,g,b,a)) -> None
?| ? ? ?sets the bit shifts needed to convert between a color and a mapped integer
?| ?
?| ?subsurface(...)
?| ? ? ?subsurface(Rect) -> Surface
?| ? ? ?create a new surface that references its parent
?| ?
?| ?unlock(...)
?| ? ? ?unlock() -> None
?| ? ? ?unlock the Surface memory from pixel access
?| ?
?| ?unmap_rgb(...)
?| ? ? ?unmap_rgb(mapped_int) -> Color
?| ? ? ?convert a mapped integer color value into a Color


另外增加了3個狀態變量,初始狀態為:

? ? is_running = False
? ? is_paused = False
? ? is_dead = False

增加了4個按鍵判別:

is_dead時,判斷重新開始還是退出游戲

pygame.K_y: 字母Y/y
pygame.K_n: 字母N/n

暫停和恢復

pygame.K_ESCAPE: Esc鍵
pygame.K_SPACE: 空格鍵

完整代碼如下:

import pygame
import sys
import random# 定義顏色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED   = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE  = (0, 0, 255)
GREY  = (220, 220, 220)  # 淡灰色
DARK  = (120, 120, 120)  # 深灰色def init():global screen, screen_sizeglobal snake_pos, food_pos, snake_speed# 初始化pygamepygame.init()# 設置屏幕大小screen_size = (640, 480)screen = pygame.display.set_mode(screen_size)# 設置游戲標題pygame.display.set_caption("貪吃蛇")# 蛇的初始位置snake_pos = [[100, 100], [80, 100], [60, 100]]# 食物的初始位置food_pos = [300, 300]# 蛇的初始速度snake_speed = [20, 0]def show_msg(msg, color = BLUE):x = screen.get_rect().centerxy = screen.get_rect().centery - 50font = pygame.font.Font(None, 36)text = font.render(msg, True, color)text_rect = text.get_rect()text_rect.centerx = xtext_rect.centery = yrectangle1 = pygame.Rect(x-155, y-25, 320, 60)rectangle2 = pygame.Rect(x-160, y-30, 320, 60)pygame.draw.rect(screen, DARK, rectangle1)pygame.draw.rect(screen, GREY, rectangle2)pygame.draw.rect(screen, BLACK, rectangle2, 2) # 邊框寬為2screen.blit(text, text_rect)pygame.display.flip()def repaint():# 繪制游戲界面screen.fill(WHITE)# 定義線段的端點坐標x,y = (-1,640,640,-1)*16, []for i in range(36):for _ in range(2):y.append(19+i*20)# 使用pygame.draw.lines()函數繪制線段points = list(zip(x,y))pygame.draw.lines(screen, GREY, False, points, 1) # 線寬為1points = list(zip(y,x))pygame.draw.lines(screen, GREY, False, points, 1)   # 重畫蛇和食物for pos in snake_pos:pygame.draw.rect(screen, GREEN, pygame.Rect(pos[0], pos[1], 20, 20))pygame.draw.rect(screen, RED, pygame.Rect(food_pos[0], food_pos[1], 20, 20))pygame.display.flip()def game_quit():pygame.quit()sys.exit()def main():global screen, screen_sizeglobal snake_pos, food_pos, snake_speedis_running = Falseis_paused = Falseis_dead = Falserepaint()show_msg("Press any key to start ...")# 主循環while True:# 處理游戲事件for event in pygame.event.get():if event.type == pygame.QUIT:game_quit()elif event.type == pygame.KEYDOWN:if event.key == pygame.K_UP:snake_speed = [0, -20]elif event.key == pygame.K_DOWN:snake_speed = [0, 20]elif event.key == pygame.K_LEFT:snake_speed = [-20, 0]elif event.key == pygame.K_RIGHT:snake_speed = [20, 0]elif event.key == pygame.K_y:if is_dead:init()is_dead = Falseis_running = Trueelif event.key == pygame.K_n:if is_dead: game_quit()else: is_running = Trueelif event.key == pygame.K_ESCAPE:if is_running:show_msg(">>> Paused <<<")is_paused = not is_pausedelse: # 任意鍵進入開始狀態is_running = Trueif not is_running: continueif is_paused and is_running: continue# 更新蛇的位置snake_pos.insert(0, [snake_pos[0][0] + snake_speed[0], snake_pos[0][1] + snake_speed[1]])# 檢查蛇頭是否碰到食物if snake_pos[0] == food_pos:food_pos = [random.randrange(1, screen_size[0] // 20) * 20, random.randrange(1, screen_size[1] // 20) * 20]else:snake_pos.pop()# 檢查蛇頭是否碰到墻壁或者蛇身if snake_pos[0][0] < 0 or snake_pos[0][0] >= screen_size[0] or snake_pos[0][1] < 0 or snake_pos[0][1] >= screen_size[1] or snake_pos[0] in snake_pos[1:]:show_msg("Dead! Again? (Y or N)")is_running = Falseis_dead = Truecontinue# 重畫界面及蛇和食物repaint()# 控制游戲速度pygame.time.Clock().tick(10)if __name__ == "__main__":init()main()

改進過程二

增加顯示得分

每吃到一個食物+10分,蛇長和食物靠近邊界會有額外加分;順帶顯示出蛇的坐標位置。

函數show_msg_at(),比show_msg增加x,y坐標,把信息顯示到指定的位置:

def show_msg_at(x, y, msg):
? ? font = pygame.font.SysFont('Consolas', 14)? # 使用系統字庫
? ? text = font.render(msg, True, BLACK)
? ? text_rect = text.get_rect()
? ? text_rect.x, text_rect.y = x, y
? ? screen.blit(text, text_rect)
? ? pygame.display.flip()

另外新增一個全局變量?scores,當碰到食物時加10分,蛇長超過5以及食物靠近邊界的距離小3會有額外加分,規則可以自己定,例如:

? ? ? ? if snake_pos[0] == food_pos:
? ? ? ? ? ? scores += 10?+ len(snake_pos) // 5
? ? ? ? ? ? if not 1 < snake_pos[0][0]//20 < 30 or not 1 < snake_pos[0][1]//20 < 22:
? ? ? ? ? ? ? ? scores += 5
?

完整代碼如下:?

import pygame
import sys
import random# 定義顏色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED   = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE  = (0, 0, 255)
GREY  = (220, 220, 220)  # 淡灰色
DARK  = (120, 120, 120)  # 深灰色def init():global screen, screen_size, scoresglobal snake_pos, food_pos, snake_speed# 初始化pygamescores = 0pygame.init()# 設置屏幕大小screen_size = (640, 480)screen = pygame.display.set_mode(screen_size)# 設置游戲標題pygame.display.set_caption("貪吃蛇")# 蛇的初始位置snake_pos = [[100, 100], [80, 100], [60, 100]]# 食物的初始位置food_pos = [300, 300]# 蛇的初始速度snake_speed = [20, 0]def show_msg(msg, color = BLUE):x = screen.get_rect().centerxy = screen.get_rect().centery - 50font = pygame.font.Font(None, 36)text = font.render(msg, True, color)text_rect = text.get_rect()text_rect.centerx = xtext_rect.centery = yrectangle1 = pygame.Rect(x-155, y-25, 320, 60)rectangle2 = pygame.Rect(x-160, y-30, 320, 60)pygame.draw.rect(screen, DARK, rectangle1)pygame.draw.rect(screen, GREY, rectangle2)pygame.draw.rect(screen, BLACK, rectangle2, 2) # 邊框寬為2screen.blit(text, text_rect)pygame.display.flip()def repaint():# 繪制游戲界面screen.fill(WHITE)# 定義線段的端點坐標x,y = (-1,640,640,-1)*16, []for i in range(36):for _ in range(2):y.append(19+i*20)# 使用pygame.draw.lines()函數繪制線段points = list(zip(x,y))pygame.draw.lines(screen, GREY, False, points, 1) # 線寬為1points = list(zip(y,x))pygame.draw.lines(screen, GREY, False, points, 1)   # 重畫蛇和食物for pos in snake_pos:pygame.draw.rect(screen, GREEN, pygame.Rect(pos[0], pos[1], 20, 20))pygame.draw.rect(screen, RED, pygame.Rect(food_pos[0], food_pos[1], 20, 20))pygame.display.flip()show_msg_at(22, 6, f'Scores: {scores}')show_msg_at(410, 6, f'Snake coordinate: ({1+snake_pos[0][0]//20:2}, {1+snake_pos[0][1]//20:2})')def show_msg_at(x, y, msg):font = pygame.font.SysFont('Consolas', 14)text = font.render(msg, True, BLACK)text_rect = text.get_rect()text_rect.x, text_rect.y = x, yscreen.blit(text, text_rect)pygame.display.flip()def game_quit():pygame.quit()sys.exit()def main():global screen, screen_size, scoresglobal snake_pos, food_pos, snake_speedis_running = Falseis_paused = Falseis_dead = Falserepaint()show_msg("Press any key to start ...")# 主循環while True:# 處理游戲事件for event in pygame.event.get():if event.type == pygame.QUIT:game_quit()elif event.type == pygame.KEYDOWN:if event.key == pygame.K_UP:snake_speed = [0, -20]elif event.key == pygame.K_DOWN:snake_speed = [0, 20]elif event.key == pygame.K_LEFT:snake_speed = [-20, 0]elif event.key == pygame.K_RIGHT:snake_speed = [20, 0]elif event.key == pygame.K_y:if is_dead:init()is_dead = Falseis_running = Trueelif event.key == pygame.K_n:if is_dead: game_quit()else: is_running = Trueelif event.key == pygame.K_SPACE:if is_dead: continueif is_paused: is_paused = Falseis_running = Trueelif event.key == pygame.K_ESCAPE:if is_running:show_msg(">>> Paused <<<")is_paused = not is_pausedelse: # 任意鍵進入開始狀態if is_dead: continueis_running = Trueif not is_running: continueif is_paused and is_running: continue# 更新蛇的位置snake_pos.insert(0, [snake_pos[0][0] + snake_speed[0], snake_pos[0][1] + snake_speed[1]])# 檢查蛇頭是否碰到食物if snake_pos[0] == food_pos:scores += 10?+ len(snake_pos) // 5if not 1 < snake_pos[0][0]//20 < 30 or not 1 < snake_pos[0][1]//20 < 22:scores += 5????????food_pos = [random.randrange(1, screen_size[0] // 20) * 20, random.randrange(1, screen_size[1] // 20) * 20]else:snake_pos.pop()# 檢查蛇頭是否碰到墻壁或者蛇身if snake_pos[0][0] < 0 or snake_pos[0][0] >= screen_size[0] or snake_pos[0][1] < 0 or snake_pos[0][1] >= screen_size[1] or snake_pos[0] in snake_pos[1:]:show_msg("Dead! Again? (Y or N)")is_running = Falseis_dead = Truecontinue# 重畫界面及蛇和食物repaint()# 控制游戲速度pygame.time.Clock().tick(10)if __name__ == "__main__":init()main()

改進過程三

增加背景景樂

def play_music(mp3, volume = 1, loops = -1):
? ? # 初始化pygame的mixer模塊
? ? pygame.mixer.init()
? ? # 加載音樂文件
? ? pygame.mixer.music.load(mp3)
? ? # 控制音量?volume = 0~1,1為最高音量
? ? pygame.mixer.music.set_volume(volume)
? ? # 播放音樂 loops = -1 為循環播放
? ? pygame.mixer.music.play(loops)

增加提示音效

def play_sound(wav_no):
? ? sound_fn = f'sound{wav_no}.wav'
? ? if os.path.exists(sound_fn):
? ? ? ? alert_sound = pygame.mixer.Sound(sound_fn)
? ? ? ? alert_sound.play()

音樂切換

快捷鍵 Ctrl+M?

? ? elif event.key == pygame.K_m and event.mod & pygame.KMOD_CTRL:
? ? ? ? # Ctrl+M 切換背景音樂
? ? ? ? is_mute = False
? ? ? ? music_no = 1 if music_no == 3 else music_no + 1
? ? ? ? music_fn = f"voice{music_no}.mp3"
? ? ? ? if os.path.exists(music_fn):
? ? ? ? ? ? t = threading.Thread(target=play_music, args=(music_fn,0.8,))
? ? ? ? ? ? t.start()

靜音切換

快捷鍵 Ctrl+S

? ? elif event.key == pygame.K_s and event.mod & pygame.KMOD_CTRL:
? ? ? ? # Ctrl+S 切換靜音狀態
? ? ? ? is_mute = not is_mute
? ? ? ? if is_mute:
? ? ? ? ? ? pygame.mixer.music.pause()
? ? ? ? else:
? ? ? ? ? ? pygame.mixer.music.unpause()

mixer.music.play 注意事項

1. pygame.mixer.music.play() 只能播放pygame支持的音頻格式,包括WAV, MP3等。

2. 如果音頻文件未找到或無法讀取,pygame.mixer.music.play( ) 會拋出一個異常。使用需要確保音頻文件的路徑正確,且文件存在。導入os庫,用os.path.exists(music_file) 判斷文件是否存在。

3. pygame.mixer.music.play() 是一個阻塞函數,在音頻播放期間程序將不會執行其他操作。如果需要在播放同時執行其他操作,需要在一個單獨的線程中調用pygame.mixer.music.play()。

4. 多線程需要導入threading庫,例如:

? ? ? ? ??t = threading.Thread(target=play_music, args=(music_fn,0.8,))
? ? ? ? ? t.start()


原版幫助摘要

pygame.mixer

NAME
? ? pygame.mixer_music - pygame module for controlling streamed audio

FUNCTIONS
? ? fadeout(...)
? ? ? ? fadeout(time) -> None
? ? ? ? stop music playback after fading out
? ??
? ? get_busy(...)
? ? ? ? get_busy() -> bool
? ? ? ? check if the music stream is playing
? ??
? ? get_endevent(...)
? ? ? ? get_endevent() -> type
? ? ? ? get the event a channel sends when playback stops
? ??
? ? get_pos(...)
? ? ? ? get_pos() -> time
? ? ? ? get the music play time
? ??
? ? get_volume(...)
? ? ? ? get_volume() -> value
? ? ? ? get the music volume
? ??
? ? load(...)
? ? ? ? load(filename) -> None
? ? ? ? load(fileobj, namehint=) -> None
? ? ? ? Load a music file for playback
? ??
? ? pause(...)
? ? ? ? pause() -> None
? ? ? ? temporarily stop music playback
? ??
? ? play(...)
? ? ? ? play(loops=0, start=0.0, fade_ms=0) -> None
? ? ? ? Start the playback of the music stream
? ??
? ? queue(...)
? ? ? ? queue(filename) -> None
? ? ? ? queue(fileobj, namehint=, loops=0) -> None
? ? ? ? queue a sound file to follow the current
? ??
? ? rewind(...)
? ? ? ? rewind() -> None
? ? ? ? restart music
? ??
? ? set_endevent(...)
? ? ? ? set_endevent() -> None
? ? ? ? set_endevent(type) -> None
? ? ? ? have the music send an event when playback stops
? ??
? ? set_pos(...)
? ? ? ? set_pos(pos) -> None
? ? ? ? set position to play from
? ??
? ? set_volume(...)
? ? ? ? set_volume(volume) -> None
? ? ? ? set the music volume
? ??
? ? stop(...)
? ? ? ? stop() -> None
? ? ? ? stop the music playback
? ??
? ? unload(...)
? ? ? ? unload() -> None
? ? ? ? Unload the currently loaded music to free up resources
? ??
? ? unpause(...)
? ? ? ? unpause() -> None
? ? ? ? resume paused music


pygame.mixer.Sound

class Sound(builtins.object)
?| ?Sound(filename) -> Sound
?| ?Sound(file=filename) -> Sound
?| ?Sound(file=pathlib_path) -> Sound
?| ?Sound(buffer) -> Sound
?| ?Sound(buffer=buffer) -> Sound
?| ?Sound(object) -> Sound
?| ?Sound(file=object) -> Sound
?| ?Sound(array=object) -> Sound
?| ?Create a new Sound object from a file or buffer object
?| ?
?| ?Methods defined here:
?| ?
?| ?__init__(self, /, *args, **kwargs)
?| ? ? ?Initialize self. ?See help(type(self)) for accurate signature.
?| ?
?| ?fadeout(...)
?| ? ? ?fadeout(time) -> None
?| ? ? ?stop sound playback after fading out
?| ?
?| ?get_length(...)
?| ? ? ?get_length() -> seconds
?| ? ? ?get the length of the Sound
?| ?
?| ?get_num_channels(...)
?| ? ? ?get_num_channels() -> count
?| ? ? ?count how many times this Sound is playing
?| ?
?| ?get_raw(...)
?| ? ? ?get_raw() -> bytes
?| ? ? ?return a bytestring copy of the Sound samples.
?| ?
?| ?get_volume(...)
?| ? ? ?get_volume() -> value
?| ? ? ?get the playback volume
?| ?
?| ?play(...)
?| ? ? ?play(loops=0, maxtime=0, fade_ms=0) -> Channel
?| ? ? ?begin sound playback
?| ?
?| ?set_volume(...)
?| ? ? ?set_volume(value) -> None
?| ? ? ?set the playback volume for this Sound
?| ?
?| ?stop(...)
?| ? ? ?stop() -> None
?| ? ? ?stop sound playback


完整代碼:

import pygame
import sys, os
import random
import threading# 定義顏色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED   = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE  = (0, 0, 255)
GREY  = (220, 220, 220)  # 淡灰色
DARK  = (120, 120, 120)  # 深灰色def init():global screen, screen_size, scoresglobal snake_pos, food_pos, snake_speed# 初始化pygamescores = 0pygame.init()# 設置屏幕大小screen_size = (640, 480)screen = pygame.display.set_mode(screen_size)# 設置游戲標題pygame.display.set_caption("貪吃蛇")# 蛇的初始位置snake_pos = [[100, 100], [80, 100], [60, 100]]# 食物的初始位置food_pos = [300, 300]# 蛇的初始速度snake_speed = [20, 0]def play_music(mp3, volume = 1, loops = -1):# 初始化pygame的mixer模塊pygame.mixer.init()# 加載音樂文件pygame.mixer.music.load(mp3)# 控制音量pygame.mixer.music.set_volume(volume)# 播放音樂pygame.mixer.music.play(loops)def play_sound(wav_no):sound_fn = f'sound{wav_no}.wav'if os.path.exists(sound_fn):alert_sound = pygame.mixer.Sound(sound_fn)alert_sound.play()def show_msg(msg, color = BLUE):x = screen.get_rect().centerxy = screen.get_rect().centery - 50font = pygame.font.Font(None, 36)text = font.render(msg, True, color)text_rect = text.get_rect()text_rect.centerx = xtext_rect.centery = yrectangle1 = pygame.Rect(x-155, y-25, 320, 60)rectangle2 = pygame.Rect(x-160, y-30, 320, 60)pygame.draw.rect(screen, DARK, rectangle1)pygame.draw.rect(screen, GREY, rectangle2)pygame.draw.rect(screen, BLACK, rectangle2, 2) # 邊框寬為2screen.blit(text, text_rect)pygame.display.flip()def repaint():# 繪制游戲界面screen.fill(WHITE)# 定義線段的端點坐標x,y = (-1,640,640,-1)*16, []for i in range(36):for _ in range(2):y.append(19+i*20)# 使用pygame.draw.lines()函數繪制線段points = list(zip(x,y))pygame.draw.lines(screen, GREY, False, points, 1) # 線寬為1points = list(zip(y,x))pygame.draw.lines(screen, GREY, False, points, 1)   # 重畫蛇和食物for pos in snake_pos:pygame.draw.rect(screen, GREEN, pygame.Rect(pos[0], pos[1], 20, 20))pygame.draw.rect(screen, RED, pygame.Rect(food_pos[0], food_pos[1], 20, 20))pygame.display.flip()show_msg_at(22, 6, f'Scores: {scores}')show_msg_at(410, 6, f'Snake coordinate: ({1+snake_pos[0][0]//20:2}, {1+snake_pos[0][1]//20:2})')def show_msg_at(x, y, msg):font = pygame.font.SysFont('Consolas', 14)text = font.render(msg, True, BLACK)text_rect = text.get_rect()text_rect.x, text_rect.y = x, yscreen.blit(text, text_rect)pygame.display.flip()def game_quit():pygame.quit()sys.exit()def main():global screen, screen_size, scoresglobal snake_pos, food_pos, snake_speedis_running = Falseis_paused = Falseis_dead = Falseis_mute = Falserepaint()show_msg("Press any key to start ...")# 創建一個線程來播放音樂music_no = 1music_fn = "voice1.mp3"if os.path.exists(music_fn):t = threading.Thread(target=play_music, args=(music_fn,0.8,))t.start()# 主循環while True:# 處理游戲事件for event in pygame.event.get():if event.type == pygame.QUIT:game_quit()elif event.type == pygame.KEYDOWN:if event.key == pygame.K_UP:snake_speed = [0, -20]elif event.key == pygame.K_DOWN:snake_speed = [0, 20]elif event.key == pygame.K_LEFT:snake_speed = [-20, 0]elif event.key == pygame.K_RIGHT:snake_speed = [20, 0]elif event.key == pygame.K_y:if is_dead:init()is_dead = Falseis_running = Trueelif event.key == pygame.K_n:if is_dead: game_quit()else: is_running = Trueelif event.key == pygame.K_SPACE:if is_dead: continueif is_paused: is_paused = Falseis_running = Trueelif event.key == pygame.K_ESCAPE:if is_running:show_msg(">>> Paused <<<")is_paused = not is_pausedif not is_mute and is_paused: play_sound(1)elif event.key == pygame.K_m and event.mod & pygame.KMOD_CTRL:# Ctrl+M 切換背景音樂is_mute = Falsemusic_no = 1 if music_no == 3 else music_no + 1music_fn = f"voice{music_no}.mp3"if os.path.exists(music_fn):t = threading.Thread(target=play_music, args=(music_fn,0.8,))t.start()elif event.key == pygame.K_s and event.mod & pygame.KMOD_CTRL:# Ctrl+S 切換靜音狀態is_mute = not is_muteif is_mute:pygame.mixer.music.pause()else:pygame.mixer.music.unpause()is_running = Trueelse: # 任意鍵進入開始狀態if is_dead: continueis_running = Trueif not is_running: continueif is_paused and is_running: continue# 更新蛇的位置snake_pos.insert(0, [snake_pos[0][0] + snake_speed[0], snake_pos[0][1] + snake_speed[1]])# 檢查蛇頭是否碰到食物if snake_pos[0] == food_pos:scores += 10 + len(snake_pos) // 5if not 1 < snake_pos[0][0]//20 < 30 or not 1 < snake_pos[0][1]//20 < 22:scores += 5if not is_mute: play_sound(2)food_pos = [random.randrange(1, screen_size[0] // 20) * 20, random.randrange(1, screen_size[1] // 20) * 20]else:snake_pos.pop()# 檢查蛇頭是否碰到墻壁或者蛇身if snake_pos[0][0] < 0 or snake_pos[0][0] >= screen_size[0] or snake_pos[0][1] < 0 or snake_pos[0][1] >= screen_size[1] or snake_pos[0] in snake_pos[1:]:show_msg("Dead! Again? (Y or N)")is_running = Falseis_dead = Trueif not is_mute: play_sound(3)continue# 重畫界面及蛇和食物repaint()# 控制游戲速度pygame.time.Clock().tick(10)if __name__ == "__main__":init()main()

小結

本文以貪吃蛇游戲為例,對pygame編程的一個簡單框架進行了深入的學習,包括對畫圖、字體、音樂等各個方面操作的各種方法和函數,學習后在pygame這方面的編程能力有所長進提高。

pygame編程框架

import pygame
import sys# 初始化Pygame
pygame.init()# 設置窗口大小
screen_size = (800, 600)# 創建窗口
screen = pygame.display.set_mode(screen_size)# 設置窗口標題
pygame.display.set_caption("Pygame Example")# 主循環
while True:# 處理事件for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()sys.exit()elif event.type == ...... // 處理按鍵事件# 填充背景色screen.fill((255, 255, 255))# 繪制矩形pygame.draw.rect(screen, (0, 0, 255), (400, 300, 100, 50))# 更新顯示pygame.display.flip()

最終版的源代碼及音樂文件列表如下:

下載地址:?

https://download.csdn.net/download/boysoft2002/88231961

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/43220.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/43220.shtml
英文地址,請注明出處:http://en.pswp.cn/news/43220.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

kvm和vmware有什么區別?如何選擇?

一、kvm和vmware的區別 VMware vSphere 平臺 VMware 可以提供 ESXi 虛擬機監控程序和 vSphere 虛擬化平臺。VMware ESXi 是一個能夠直接安裝到物理服務器上的裸機虛擬機監控程序&#xff0c;可以幫你整合硬件。你可以用 VMware 的虛擬化技術來創建和部署虛擬機&#xff08;VM…

HTML詳解連載(7)

HTML詳解連載&#xff08;7&#xff09; 專欄鏈接 [link](http://t.csdn.cn/xF0H3)下面進行專欄介紹 開始嘍結構偽類選擇器作用 :nth-child&#xff08;公式&#xff09;作用舉例 偽元素選擇器作用注意&#xff1a; PxCoook作用盒子模型-重要組成部分 盒子模型-邊框線屬性名屬性…

excel中定位條件,excel中有哪些數據類型、excel常見錯誤值、查找與替換

一、如何定位條件 操作步驟&#xff1a;開始 - 查找和選擇 - 定位條件&#xff08;ctrl G 或 F5&#xff09; 注&#xff1a;如果F5不可用&#xff0c;可能是這個快捷鍵被占用了 案例&#xff1a;使用定位條件選擇取余中空單元格&#xff0c;填入100&#xff0c;按組合鍵ct…

【LeetCode75】第三十三題 二叉樹的最大深度

目錄 題目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代碼&#xff1a; 題目&#xff1a; 示例&#xff1a; 分析&#xff1a; 從這一題開始&#xff0c;LeetCode75進入到了二叉樹章節。 這邊建議不熟悉二叉樹的小伙伴可以先去做做力扣的前序遍歷&#xff0c;中序遍…

使用git rebase 之后的如何恢復到原始狀態

我們常常喜歡使用git rebase去切換分支提交代碼,操作流程就是: 先切換分支:比如當前是master 我們修改了一堆代碼產生一個commit id :5555555567777 那么我們常常比較懶就直接切換了:git checkout dev 然后呢?使用命令git rebase 5555555567777,想把這筆修改提交到d…

iPhone上的個人熱點丟失了怎么辦?如何修復iPhone上不見的個人熱點?

個人熱點功能可將我們的iPhone手機轉變為 Wi-Fi 熱點&#xff0c;有了Wi-Fi 熱點后就可以與附近的其他設備共享其互聯網連接。 一般情況下&#xff0c;個人熱點打開就可以使用&#xff0c;但也有部分用戶在升級系統或越獄后發現 iPhone 的個人熱點消失了。 iPhone上的個人熱點…

antd5源碼調試環境搭建(window系統)

將antd源碼克隆至本地 $ git clone gitgithub.com:ant-design/ant-design.git $ cd ant-design $ npm install $ npm start前提安裝python3、安裝node版本18版本 不然后續安裝依賴會報python3相關的錯誤。 項目需要使用git 初始化 不然會報husky相關的錯誤 git init重新安…

【論文解讀】Hybrid-SORT: Weak Cues Matter for Online Multi-Object Tracking

因為Hybrid-SORT的baseline是基于OCSORT進行改進的&#xff0c;在這之前建議先了解byteTrack和【】的相關知識 1.介紹 1.1 基本框架 多目標跟蹤(MOT)將問題分為兩個子任務。第一個任務是檢測每個幀中的對象。第二個任務是將它們在不同的框架中聯系起來。關聯任務主要通過顯式…

RabbitMq-發布確認高級(避坑指南版)

在初學rabbitMq的時候&#xff0c;伙伴們肯定已經接觸到了“發布確認”的概念&#xff0c;但是到了后期學習中&#xff0c;會接觸到“springboot”中使用“發布確認”高級的概念。后者主要是解決什么問題呢&#xff1f;或者是什么樣的場景引出這樣的概念呢&#xff1f; 在生產環…

day45 ● 70. 爬樓梯 (進階)● 322. 零錢兌換 ● 279.完全平方數

70. 爬樓梯 class Solution {public int climbStairs(int n) {if(n <2) return n;int[] dp new int [n];dp[0] 1;dp[1] 2;for(int i 2; i< n;i){dp[i] dp[i-1] dp[i-2];}return dp[n-1];} } 322. 零錢兌換 class Solution {public int coinChange(int[] coins, in…

為什么kafka 需要 subscribe 的 group.id?我們是否需要使用 commitSync 手動提交偏移量?

目錄 一、為什么需要帶有 subscribe 的 group.id二、我們需要使用commitSync手動提交偏移量嗎&#xff1f;三、如果我想手動提交偏移量&#xff0c;該怎么做&#xff1f; 一、為什么需要帶有 subscribe 的 group.id 消費概念&#xff1a; Kafka 使用消費者組的概念來實現主題的…

vscode | linux | c++ intelliense 被棄用解決方案

每日一句&#xff0c;vscode用的爽是爽&#xff0c;主要是可配置太強了。如果也很會研究&#xff0c;可以直接去咸魚接單了 廢話少說&#xff0c;直接整。 用著用著說是c intelliense被棄用&#xff0c;很多輔助功能無法使用&#xff0c;像查看定義、查看引用、函數跳轉、智能提…

基于Rust的QuickLZ壓縮算法的詳細實現與分析

1. 引言 QuickLZ是一種被廣泛應用的高效壓縮算法。在許多應用中&#xff0c;快速的數據壓縮和解壓縮是非常關鍵的&#xff0c;特別是在網絡傳輸和存儲空間有限的場景中。為了滿足現代軟件開發的需求&#xff0c;我們將使用Rust語言來實現這一算法。Rust是一種專為系統級編程而…

Nodejs沙箱逃逸--總結

一、沙箱逃逸概念 JavaScript和Nodejs之間有什么區別&#xff1a;JavaScript用在瀏覽器前端&#xff0c;后來將Chrome中的v8引擎單獨拿出來為JavaScript單獨開發了一個運行環境&#xff0c;因此JavaScript也可以作為一門后端語言&#xff0c;寫在后端&#xff08;服務端&#…

七夕特輯——3D愛心(可監聽鼠標移動)

前言 「作者主頁」&#xff1a;雪碧有白泡泡 「個人網站」&#xff1a;雪碧的個人網站 「推薦專欄」&#xff1a; ★java一站式服務 ★ ★ React從入門到精通★ ★前端炫酷代碼分享 ★ ★ 從0到英雄&#xff0c;vue成神之路★ ★ uniapp-從構建到提升★ ★ 從0到英雄&#xff…

【005】ts學習筆記【函數擴展】

函數擴展 參數類型 //注意&#xff0c;參數不能多傳&#xff0c;也不能少傳 必須按照約定的類型來 const fn (name: string , age : number ) : string > {return name age }let desc fn( "張三", 18) console.log(desc)可選參數與默認值 //可選的參數 和 默…

深入理解Flink Mailbox線程模型

文章目錄 整體設計processMail1.Checkpoint Tigger2.ProcessingTime Timer Trigger processInput兼容SourceStreamTask 整體設計 Mailbox線程模型通過引入阻塞隊列配合一個Mailbox線程的方式&#xff0c;可以輕松修改StreamTask內部狀態的修改。Checkpoint、ProcessingTime Ti…

@Repeatable的作用以及具體如何使用

文章目錄 1. 前言2. 先說結論3. 案例演示 1. 前言 最近無意看到某些注解上有Repeatable&#xff0c;出于比較好奇&#xff0c;因此稍微研究并寫下此文章。 2. 先說結論 Repeatable的作用&#xff1a;使被他注釋的注解可以在同一個地方重復使用。 具體使用如下&#xff1a; T…

CentOS7源碼安裝MySQL詳細教程

&#x1f60a; 作者&#xff1a; Eric &#x1f496; 主頁&#xff1a; https://blog.csdn.net/weixin_47316183?typeblog &#x1f389; 主題&#xff1a;CentOS7源碼安裝MySQL詳細教程 ?? 創作時間&#xff1a; 2023年08月014日 文章目錄 1、安裝的四種方式2、源碼安裝…

深度解析:DDoS攻擊與先進防御策略

目錄 DDoS 介紹 DDoS 攻擊理論 DDoS 介紹 DDoS&#xff08;分布式拒絕服務&#xff09;攻擊是一種惡意網絡活動&#xff0c;旨在通過同時向目標系統發送大量請求或流量&#xff0c;使其無法正常運行或提供服務。攻擊者通常利用網絡上的多個計算機和設備&#xff0c;形成一個&…