day19、pygame 和 多線程 2019-01-17

一、事件

游戲中的事件

1.鼠標(biāo)相關(guān)的事件

(1)pygame.MOUSEBUTTONDOWN
鼠標(biāo)摁下的事件
(2)pygame.MOUSEBUTTONUP
鼠標(biāo)彈起的事件
(3)pygame.MOUSEMOTION
鼠標(biāo)移動的事件(只要移動后會產(chǎn)生事件)

鼠標(biāo)事件要關(guān)注事件發(fā)生的位置:
event.pos -----產(chǎn)生鼠標(biāo)摁下的坐標(biāo),產(chǎn)生一個元組

2.鍵盤事件

(1)pygame.KEYDOWN
鍵盤被摁下
(2)pygame.KEYUP
鍵盤彈起來

鍵盤事件要關(guān)注哪個鍵被摁了:
event.key -----產(chǎn)生摁下的按鍵對應(yīng)的字符編碼值
例如:

import pygame
import color
from random import randint


def main():
    pygame.init()
    window1 = pygame.display.set_mode((600, 400))
    pygame.display.set_caption('事件')
    window1.fill(color.Color.gray)

    pygame.display.flip()

    flag = False
    while True:
        # 不斷檢測是否有事件發(fā)生,如果有,就進入 for 循環(huán)
        for event in pygame.event.get():
            # 這里的 event 是事件對象,我們可以通過事件對象的 type 值來判斷事件的類型
            if event.type == pygame.QUIT:
                # 退出 pygame
                exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                # 鼠標(biāo)摁下的事件, 鼠標(biāo)摁下后要干什么就寫在這里面
                print('鼠標(biāo)摁下', event.pos)
                pygame.draw.circle(window1, color.Color.random_color(), event.pos, randint(5, 50))
                flag = True
            elif event.type == pygame.MOUSEBUTTONUP:
                # 鼠標(biāo)彈起的事件, 鼠標(biāo)彈起后要干什么就寫在這里面
                print('鼠標(biāo)彈起')
                flag = False
            elif event.type == pygame.MOUSEMOTION:
                # 鼠標(biāo)移動的事件, 鼠標(biāo)移動時要干什么就寫在這里面
                if flag:
                    print('鼠標(biāo)移動')

            # 鍵盤事件
            if event.type == pygame.KEYDOWN:
                print('鍵盤被摁下', chr(event.key))
            elif event.type == pygame.KEYUP:
                print('鍵盤彈起來')


if __name__ == '__main__':
    main()

運行結(jié)果:


硬盤事件

二、按鈕

例如:

import pygame
import color


class Button:
    def __init__(self, x, y, h, w, text='', background_color='', text_color=''):
        self.x = x
        self.y = y
        self.h = h
        self.w = w
        self.text = text
        self.background_color = background_color
        self.text_color = text_color

    def add_btn(self, window1):
        pygame.draw.rect(window1, color.Color.gray, (self.x, self.y, self.h, self.w))
        font = pygame.font.SysFont('Times', 30)
        test = font.render('add', True, color.Color.yellow)
        w, h = test.get_size()
        x = 100 / 2 - w / 2 + 100
        y = 200 / 2 - h / 2 + 100
        window1.blit(test, (x, y))


def main():
    pygame.init()
    window1 = pygame.display.set_mode((600, 400))

    add_btn = Button(100, 100, 50, 50, )

    while True:
        # 不斷檢測是否有事件發(fā)生,如果有,就進入 for 循環(huán)
        for event in pygame.event.get():
            # 這里的 event 是事件對象,我們可以通過事件對象的 type 值來判斷事件的類型
            if event.type == pygame.QUIT:
                # 退出 pygame
                exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                # 鼠標(biāo)摁下的事件, 鼠標(biāo)摁下后要干什么就寫在這里面
                mx, my = event.pos
                if (100 <= mx <= 100 + 100) and (100 <= my < 100 + 200):
                    print('鼠標(biāo)摁下')
            elif event.type == pygame.MOUSEBUTTONUP:
                # 鼠標(biāo)彈起的事件, 鼠標(biāo)彈起后要干什么就寫在這里面
                print('鼠標(biāo)彈起')
            elif event.type == pygame.MOUSEMOTION:
                # 鼠標(biāo)移動的事件, 鼠標(biāo)移動時要干什么就寫在這里面
                print('鼠標(biāo)移動')


if __name__ == '__main__':
    main()

運行結(jié)果:


按鈕

三、移動操作

例如:

import pygame
import color


class Button:
    def __init__(self, x, y, h, w, text='', background_color='', text_color=''):
        self.x = x
        self.y = y
        self.h = h
        self.w = w
        self.text = text
        self.background_color = background_color
        self.text_color = text_color

    def add_btn(self, window1):
        pygame.draw.rect(window1, color.Color.gray, (self.x, self.y, self.h, self.w))
        font = pygame.font.SysFont('Times', 30)
        test = font.render('add', True, color.Color.yellow)
        w, h = test.get_size()
        x = 100 / 2 - w / 2 + 100
        y = 200 / 2 - h / 2 + 100
        window1.blit(test, (x, y))


def main():
    pygame.init()
    window1 = pygame.display.set_mode((600, 400))

    add_btn = Button(100, 100, 50, 50, )

    while True:
        # 不斷檢測是否有事件發(fā)生,如果有,就進入 for 循環(huán)
        for event in pygame.event.get():
            # 這里的 event 是事件對象,我們可以通過事件對象的 type 值來判斷事件的類型
            if event.type == pygame.QUIT:
                # 退出 pygame
                exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                # 鼠標(biāo)摁下的事件, 鼠標(biāo)摁下后要干什么就寫在這里面
                mx, my = event.pos
                # if (100 <= mx <= 100 + 100) and (100 <= my < 100 + 200):
                print('鼠標(biāo)摁下')
            elif event.type == pygame.MOUSEBUTTONUP:
                # 鼠標(biāo)彈起的事件, 鼠標(biāo)彈起后要干什么就寫在這里面
                print('鼠標(biāo)彈起')
            elif event.type == pygame.MOUSEMOTION:
                # 鼠標(biāo)移動的事件, 鼠標(biāo)移動時要干什么就寫在這里面
                print('鼠標(biāo)移動')


if __name__ == '__main__':
    main()

運行結(jié)果:


移動操作

四、耗時操作

默認(rèn)情況下,一個進程就只有一個線程,這個線程叫主線程
threading 模塊里的 Thread 類就是線程類,這個類的對象就是線程對象,一個線程對應(yīng)一個子線程
需要一個子線程

Thread(target, args) -----創(chuàng)建子線程對象
說明:
target -----Function ,需要傳一個函數(shù)(這個函數(shù)中的內(nèi)容會在子線程中執(zhí)行)
args -----target 對應(yīng)的函數(shù)的參數(shù)
當(dāng)通過創(chuàng)建好的子線程對象調(diào)用 start 方法的時候,會自動在子線程中調(diào)用 target 對應(yīng)的函數(shù)
并且將 args 中的值變?yōu)閷崊?br> 例如:

import time
from datetime import datetime
# python 多線程技術(shù)對應(yīng)的模塊:
import threading


def downlosd(file):
    print(' %s 下載開始' % file, datetime.now())
    # 系統(tǒng)提供的模塊.sleep(), 程序執(zhí)行到這個位置等待指定的時候再接著往后執(zhí)行
    time.sleep(5)
    print(' %s 下載結(jié)束' % file, datetime.now())


def main():
    print('程序開始')
    # 1.在主線程里下載兩個電影,(總耗時10秒)
    # downlosd('海王')
    # downlosd('阿黃正傳')

    # 創(chuàng)建子線程,同時下載兩個電影
    # Thread(target, args)          -----創(chuàng)建子線程對象
    t1 = threading.Thread(target=downlosd, args=('海王', ))
    t2 = threading.Thread(target=downlosd, args=('阿黃正傳', ))
    t3 = threading.Thread(target=downlosd, args=('殺死比爾', ))
    # 開始執(zhí)行 t1 里面的子線程中的任務(wù)(實質(zhì)就是在子線程中調(diào)用 target 對應(yīng)的函數(shù))
    t1.start()
    t2.start()
    t3.start()
    print('................')


if __name__ == '__main__':
    main()

運行結(jié)果:


耗時操作.jpg

五、線程

可以通過寫一個類,繼承 Thread 類,來創(chuàng)建屬于自己的線程類

1.聲明類繼承 Thread
2.重寫 run 方法, 這個方法中的任務(wù)就是需要在子線程中執(zhí)行的任務(wù)
3.需要線程對象的時候,創(chuàng)建子類的對象; 然后通過 start 方法在子線程中去執(zhí)行 run 方法
例如:

import threading
import time as time1
from datetime import datetime


class DownloadTread(threading.Thread):
    def __init__(self, file):
        super().__init__()
        self.file = file

    def run(self):
        print(' %s 開始下載' % self.file, datetime.now())
        print('run;', threading.current_thread())
        time1.sleep(5)
        print(' %s 下載結(jié)束' % self.file, datetime.now())


def main():
    # 獲取當(dāng)前線程
    print(threading.current_thread())

    t1 = DownloadTread('海王')
    t2 = DownloadTread('魔道祖師')
    # 調(diào)用 start 方法的時候,會自動在子線程中調(diào)用 run 方法
    t1.start()
    t2.start()

    # 如果直接調(diào)用 run 方法,方法中的任務(wù)命令就會在主線程里面執(zhí)行
    # t1.run()


if __name__ == '__main__':
    main()

運行結(jié)果:


子線程.jpg

六、join

線程對象調(diào)用 join 方法,會導(dǎo)致 join 后的代碼會在線程中的任務(wù)結(jié)束后才執(zhí)行
例如:

from threading import Thread
import requests
import re
import time


class DownloadThread2(Thread):
    """下載類"""
    def __init__(self, file, new_time):
        super().__init__()
        self.file = file
        self.time = new_time

    def run(self):
        print('開始下載:'+self.file)
        # t = randint(5, 10)
        time.sleep(self.time)
        print('%s下載結(jié)束, 總共耗時:%ds' % (self.file, self.time))


class DownloadImageThread(Thread):
    def __init__(self, url):
        super().__init__()
        self.url = url

    def run(self):
        # 開始下載
        file_name = re.split(r'/', self.url)[-1]
        print(file_name)
        print('%s開始下載' % file_name)
        response = requests.get(self.url)
        content = response.content

        with open('images/'+file_name, 'bw') as f:
            f.write(content)

        print('%s下載結(jié)束' % file_name)


def creat_thread():
    t1 = DownloadThread2('電影1', 6)
    t2 = DownloadThread2('電影2', 4)
    t1.start()
    t2.start()
    # 線程對象調(diào)用join方法,會導(dǎo)致join后的代碼會在線程中的任務(wù)結(jié)束后才執(zhí)行
    t1.join()
    t2.join()
    print('電影下載結(jié)束!')


def main():
    t0 = Thread(target=creat_thread)
    t0.start()

    print('========')
    for x in range(100):
        time.sleep(1)
        print(x)


if __name__ == '__main__':
    main()

運行結(jié)果:

C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python.exe C:/Users/Administrator/Desktop/python老師教程/第一階段/day19-pygame和多線程/day19pygame和多線程/07join.py
========
開始下載:電影1
開始下載:電影2
0
1
2
3
電影2下載結(jié)束, 總共耗時:4s
4
電影1下載結(jié)束, 總共耗時:6s
電影下載結(jié)束!
5
6
7
8
9
10

Process finished with exit code -1

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,663評論 1 32
  • ??JavaScript 與 HTML 之間的交互是通過事件實現(xiàn)的。 ??事件,就是文檔或瀏覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,696評論 1 11
  • 進程和線程 進程 所有運行中的任務(wù)通常對應(yīng)一個進程,當(dāng)一個程序進入內(nèi)存運行時,即變成一個進程.進程是處于運行過程中...
    勝浩_ae28閱讀 5,257評論 0 23
  • 文檔地址 案例代碼下載 運行循環(huán) 運行循環(huán)是與線程相關(guān)的基礎(chǔ)架構(gòu)的一部分。一個運行循環(huán)是指用于安排工作,并協(xié)調(diào)接收...
    酒茶白開水閱讀 751評論 0 0
  • 進程和線程 進程 所有運行中的任務(wù)通常對應(yīng)一個進程,當(dāng)一個程序進入內(nèi)存運行時,即變成一個進程.進程是處于運行過程中...
    小徐andorid閱讀 2,993評論 3 53

友情鏈接更多精彩內(nèi)容