Python游戲開發(三)


python游戲開發之色彩與繪圖

pygame色彩機制

  1. 使用pygame.Color類表示色彩
    Color類使用RGB或者RGBA(A代表透明度,可選)色彩模式。
    可以使用色彩名字:
    色彩的RGB或RBGA值:Color(190, 190, 190, 255)
    色彩的名字:Color("grey")
    RGB即紅綠藍三原色,范圍從0~255之間。
    A為α通道,參考值為0~255,越高越不透明

  2. pygame.Color的屬性
    pygame.Color.r Color類的R值
    pygame.Color.g Color類的G值
    pygame.Color.b Color類的B值
    pygame.Color.a Color類的A值
    pygame.Color.normalize 可以使得所有的參數歸一化一個0~1之間的浮點數

  3. 修改小球的背景顏色
    需求:通過小球運動的位置不同,分別改變其背景中R,G,B三原色的值。

import sys, pygame
pygame.init()
size = width, height = (600, 400)
speed = [1, 1]
bgcolor = pygame.Color("black")
fps = 300
still = False
icon = pygame.image.load("滑稽球1.jpg")
pygame.display.set_icon(icon)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("壁球小游戲鼠標版")
ball = pygame.image.load("滑稽球1.jpg")
ballrect = ball.get_rect()
fclock = pygame.time.Clock()

def RGBChannel(a):
    return 0 if a<0 else(255 if a>255 else(int(a)))
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                speed[0] = speed[0] if speed[0] == 0 else (abs(speed[0]) - 1) * int(speed[0] / abs(speed[0]))
            elif event.key == pygame.K_RIGHT:
                speed[0] = speed[0] + 1 if speed[0] > 0 else speed[0] - 1
            elif event.key == pygame.K_UP:
                speed[1] = speed[1] + 1 if speed[1] > 0 else speed[1] - 1
            elif event.key == pygame.K_DOWN:
                speed[1] = speed[1] if speed[1] == 0 else (abs(speed[1]) - 1) * int(speed[1] / abs(speed[1]))
            elif event.key == pygame.K_ESCAPE:
                sys.exit()
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                still = True
        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                still = False
                ballrect = ballrect.move(event.pos[0] - ballrect.left, event.pos[1] - ballrect.top)
        elif event.type == pygame.MOUSEMOTION:
            if event.buttons[0] == 1:
                ballrect = ballrect.move(event.pos[0] - ballrect.left, event.pos[1] - ballrect.top)

    if ballrect.left < 0 or ballrect.right > width:
        speed[0] = -speed[0]
        if ballrect.right > width and ballrect.right + speed[0] > ballrect.right:
            # 因為對於鼠標的控制而言,我們是設置的鼠標位置為矩形框的左上角,所以只考慮右下方突破邊界的情況
            speed[0] = -speed[0]
    elif ballrect.top < 0 or ballrect.bottom > height:
        speed[1] = -speed[1]
        if ballrect.bottom > height and ballrect.bottom + speed[1] > ballrect.bottom:
            speed[1] = -speed[1]
    if pygame.display.get_active():
        if not still:
            ballrect = ballrect.move(speed[0], speed[1])
    bgcolor.r = RGBChannel(ballrect.left/width*255)
    bgcolor.g = RGBChannel(ballrect.top/height*255)
    bgcolor.b = RGBChannel(min(speed[0], speed[1])/max(speed[0], speed[1], 1))
    screen.fill(bgcolor)
    screen.blit(ball, ballrect)
    pygame.display.update()
    fclock.tick(fps)

pygame的圖形繪制機制

所有圖形繪制之后,歐pygame都會使用一個rect類(矩形類)來表示一個范圍。

pygame.rect

表示一個矩形范圍,因而有四個基本的參數值:(left, top)矩形左上角的坐標,width,height寬度與高度,通過這四個值唯一確定矩形的位置。
同樣rect類也提供了一些方法例如:rect.move(),rect.copy()等等

pygame.draw

pygame 通過pygame.draw來繪制不同的圖形,包括矩形、圓形、橢圓等等。

  1. pygame.draw.rect(surface, color, rect, width=0)
    surface 表示的是繪制在什么區域,一般而言就是當前的屏幕screen
    color表示矩形的顏色
    rect表示矩形的區域,通過一個四元素的元組確定即左上角坐標與寬、高
    width表示的是矩形的線條寬度,默認為0即矩形全部為color顏色,如果不為0,那么就會繪制一個空心區域
import sys, pygame

pygame.init()
size = width, height = (600, 400)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("pygame圖形繪制")
gold = 255, 251, 0
red = pygame.Color("red")

rect1 = pygame.draw.rect(screen, gold, (100, 100, 200, 100), 5)
rect2 = pygame.draw.rect(screen, red, (210, 210, 200, 100))

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
    pygame.display.update()

以上是在pygame中繪制矩形的示例代碼。
2. pygame.draw.polygon(surface, color, pointlist, width=0)
多邊形需要給一個pointlist即一個頂點坐標的列表。

  1. pygame.draw.circle(surface, color, pos, radicus, width=0)
    圓形通過一個圓心坐標和半徑來繪制。

  2. pygame.draw.ellipse(surface, color, rect, width=0)
    橢圓形的定義方式是通過一個外切矩形來確定。
    rect表示一個矩形區域

  3. pygame.draw.arch(surface, color, rect, start_angle, stop_angle, width=0)
    這里繪制的是一個橢圓形的部分。
    同樣通過一個外切矩形來確定唯一的橢圓。
    start_angle來表示起始角度;
    stop_angle來表示終止角度;仍然使用的是笛卡爾坐標系。

  4. pygame.draw.line(surface, color, start_pos, end_pos, width=1)
    start_pos表示的是起始坐標;
    end_pos 表示的是終點坐標;
    默認的線條寬度是1。

  5. pygame.draw.lines(suraface, color, closed, pointlist, width=1)
    closed 如果為True會把起始和終止點連接使得多線形成閉合圖形。

  6. pygame.draw.aaline(surface, color, start_pos, end_pos, blend=1)
    直線繪制需要跨越像素,放大一定程度必然會出現鋸齒。
    pygame提供了繪制無鋸齒線的方法,注意這里的“無鋸齒”只是盡可能地減少鋸齒的出現,而不可能真的全面消除鋸齒的存在。
    blend:不為0時,與線條所在背景顏色混合。

  7. pygame.draw.aalines(surface, color, pointlist, blend=1)
    繪制無鋸齒多線。

pygame文字繪制機制

通過使用pygame.freetype來把文字繪制到屏幕上。
無論是中文還是其他語言,文字都是通過點陣圖的方式繪制到屏幕上面。
freetype是增強方法,必須要額外進行import pygame.freetype才能使用。

系統字體

對於windows系統,通常把字體存儲在C:\windows\fonts目錄下。
字體通常是*.ttc或者*.ttf格式的文件。

使用字體

首先需要創建一個字體對象。
pygame.freetype.Font來創建字體對象;
pygame.freetype.render()/render_to()來輸出字體。

  1. pygame.freetype.Font(File, size=0)
    File表示字體文件存儲的位置,建議使用絕對路徑
    size表示的字體的大小。
  2. Font.render_to(surf, dest, text, fgcolor = None, bgcolor = None, rotation, size)
    返回的是一個rect 類型。
    surf:繪制字體的平面
    dest:繪制字體的在屏幕的位置
    text:字體的內容,字符串
    fgcolor:字體顏色
    bgcolor: 背景顏色
    rotation:逆時針旋轉的角度
    size:字體的大小,如果不另外設置會使用之前的Font的大小。
import sys, pygame
import pygame.freetype

pygame.init()
size = width, height = (600, 400)
screen = pygame.display.set_mode(size)

f1 = pygame.freetype.Font("C://windows//Fonts//msyh.ttc", 36)
rect = f1.render_to(screen, (200, 160), "世界和平", )
  1. Font.render(text, fgcolor=None, bgcolor=None, rotation, size)
    相比於render_to()它少了前兩個參數。
    它會返回一個rect對象與一個surf對象,來表示把文字繪制到一個新的屏幕上。

pygame繪圖機制的精髓

  1. surface類
    表示的是繪圖平面,繪圖層、圖層;
    表示的是圖形或文字圖像最終繪制的位置。
    圖層是可以和主圖層的並列存在的,但是只有主圖層的圖像會被顯示在屏幕上。
  2. rect類
    表示一個矩形區域,但是它只對應一個主圖層上的區域。
    它是表示主圖層上某一個區域的位置信息或指針;
    可以指定某個圖層繪制在特定區域上。
  3. 主圖層
    由pygame.display.set_mode()生成的surface對象就是主圖層。
    如果希望把其他圖層的東西繪制到主圖層上就要使用blit方法,例如:
    screen.blit(ball, ballrect)
    這就是把小球的圖像ball的圖層將其繪制到ballrect的區域上。

壁球小游戲文字型

需求:把壁球替換為一段文字,可以進行移動;
關鍵要素:文字的繪制與刷新。

可以使用render_to()方法或者render()方法來繪制文字。

import sys, pygame
import pygame.freetype

pygame.init()
size = width, height = 600, 400
speed = [1, 1]
Black = 0, 0, 0
Gold = 255, 251, 0
pos = [230, 160]

screen = pygame.display.set_mode(size)
pygame.display.set_caption("pygame壁球小游戲文字型")
fps = 300
fclock = pygame.time.Clock()
f1 = pygame.freetype.Font("C://windows//Fonts//msyh.ttc", 36)
f1rect = f1.render_to(screen, pos, "世界和平", fgcolor=Gold, size=50)


while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                speed[0] = speed[0] - 1 if speed[0] > 0 else 0
            elif event.key == pygame.K_RIGHT:
                speed[0] = speed[0] + 1
            elif event.key == pygame.K_UP:
                speed[1] = speed[1] + 1
            elif event.key == pygame.K_DOWN:
                speed[1] = speed[1] - 1 if speed[1] > 0 else 0

    if pos[0] < 0 or pos[0] + f1rect.width > width:
        speed[0] = -speed[0]
    if pos[1] < 0 or pos[1] + f1rect.height > height:
        speed[1] = -speed[1]
    pos[0] = pos[0] + speed[0]
    pos[1] = pos[1] + speed[1]
    screen.fill(Black)
    f1rect = f1.render_to(screen, pos, "世界和平", fgcolor=Gold, size=50)
    pygame.display.update()
    fclock.tick(fps)

以上內容來自北京理工大學嵩天老師及其團隊的《Python游戲開發入門》課程第四周的內容。
非常感謝嵩天老師及其團隊給我們帶來這樣優質的課程。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM