Pygame - Python游戲編程入門(1)

前言

  在上一篇中,我們初步熟悉了pygame的控制流程,但這對于一個游戲而言是遠遠不夠的。所以在這一篇中,我們的任務是添加一架飛機(玩家),并且能夠控制它進行移動,這樣我們就又離目標進了一步了~ε=ε=(ノ≧?≦)ノ

?

正片開始!

1. 把我們的戰斗機搬上屏幕

  在正式上代碼以前,有一點需要說明的,我們可以看到,所有屏幕上出現的元素都在資源文件(resources/image/shoot.png)中,那我們要怎么做才能把一只飛機給裁剪出來呢?在pygame中,所有在屏幕上顯示的元素都可以視為一個surface,利用這個特點,我們可以把資源文件導入(load()函數),然后用surface.subsurface()函數把shoot.png中我們想要的元素裁剪出來,這樣問題就解決了~(tips:怎樣才知道shoot.png中飛機的準確坐標呢?在resources/image/shoot.pack文件中已經詳細記錄了每個屏幕元素的左上角坐標以及它的寬和高了)

  先上代碼:(在注釋# == new add ==之間的代碼為新加入代碼)

 1 import pygame                   # 導入pygame庫
 2 from pygame.locals import *     # 導入pygame庫中的一些常量
 3 from sys import exit            # 導入sys庫中的exit函數
 4 
 5 # 定義窗口的分辨率
 6 SCREEN_WIDTH = 480
 7 SCREEN_HEIGHT = 640
 8 
 9 # 計數ticks == new add ==
10 ticks = 0
11 # 計數ticks == new add ==
12   
13 # 初始化游戲
14 pygame.init()                   # 初始化pygame
15 screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])     # 初始化窗口
16 pygame.display.set_caption('This is my first pygame-program')       # 設置窗口標題
17 
18 # 載入背景圖
19 background = pygame.image.load('resources/image/background.png')
20 
21 # 載入資源圖片 == new add ==
22 shoot_img = pygame.image.load('resources/image/shoot.png')
23 # 用subsurface剪切讀入的圖片
24 hero1_rect = pygame.Rect(0, 99, 102, 126)
25 hero2_rect = pygame.Rect(165, 360, 102, 126)
26 hero1 = shoot_img.subsurface(hero1_rect)
27 hero2 = shoot_img.subsurface(hero2_rect)
28 hero_pos = [200, 500]
29 # 載入資源圖片 == new add ==
30 
31 # 事件循環(main loop)
32 while True:
33 
34     # 繪制背景
35     screen.blit(background, (0, 0))
36     
37     # 繪制飛機 == new add ==
38     if ticks % 50 < 25:
39         screen.blit(hero1, hero_pos)
40     else:
41         screen.blit(hero2, hero_pos)
42     ticks += 1
43     # 繪制飛機  == new add ==
44     
45     # 更新屏幕
46     pygame.display.update()                                         
47     
48     # 處理游戲退出
49     # 從消息隊列中循環取
50     for event in pygame.event.get():
51         if event.type == pygame.QUIT:
52             pygame.quit()
53             exit()

不妨運行一下:

  

可以看到,我們的飛機動了,究竟是怎樣實現動畫效果的呢?在代碼中,新加入的代碼一共有三處,顯示玩家飛機的那一段已經解釋過了,現在我們來解釋其余的兩段新加入的代碼。首先增加了一個計數變量ticks,在消息循環中,每循環一次就累加一次,可以理解為每一個周期就是1 tick,我們可以利用周期數來分隔不同的顯示效果;我們讀入了兩張不同的玩家飛機圖片,利用周期數實現每50個周期,前25個周期顯示hero1,后25個周期顯示hero2,這樣就有了緩慢變化的動態效果。不過值得注意的是,這樣每一次循環就計算判斷一次ticks的做法明顯不是好方法。還有!(╯°口°)╯(┴—┴,Python是木有自增表達式的,我試圖++ticks結果報錯了。

  戰斗機已經準備就緒,該教會飛行員怎樣操作了~(`?ω?′)

?

2. 用鍵盤控制飛機移動

  我們知道,每敲一下鍵盤都會產生一個事件,而這個事件能被Python檢測到,既然知道了這個大前提,那控制飛機就很容易了。

  come on code~?( °?°)ノ

 1 import pygame                   # 導入pygame庫
 2 from pygame.locals import *     # 導入pygame庫中的一些常量
 3 from sys import exit            # 導入sys庫中的exit函數
 4 
 5 # 定義窗口的分辨率
 6 SCREEN_WIDTH = 480
 7 SCREEN_HEIGHT = 640
 8 
 9 ticks = 0
10 # dict == new add ==
11 offset = {pygame.K_LEFT:0, pygame.K_RIGHT:0, pygame.K_UP:0, pygame.K_DOWN:0}
12 # dict == new add ==
13   
14 # 初始化游戲
15 pygame.init()                   # 初始化pygame
16 screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])     # 初始化窗口
17 pygame.display.set_caption('This is my first pygame-program')       # 設置窗口標題
18 
19 # 載入背景圖
20 background = pygame.image.load('resources/image/background.png')
21 
22 # 載入飛機圖片
23 shoot_img = pygame.image.load('resources/image/shoot.png')
24 # 用subsurface剪切讀入的圖片
25 hero1_rect = pygame.Rect(0, 99, 102, 126)
26 hero2_rect = pygame.Rect(165, 360, 102, 126)
27 hero1 = shoot_img.subsurface(hero1_rect)
28 hero2 = shoot_img.subsurface(hero2_rect)
29 hero_pos = [200, 500]
30 
31 # 事件循環(main loop)
32 while True:
33 
34     # 繪制背景
35     screen.blit(background, (0, 0))
36 
37     # 繪制飛機
38     if ticks % 50 < 25:
39         screen.blit(hero1, hero_pos)
40     else:
41         screen.blit(hero2, hero_pos)
42     ticks += 1 # python已略去自增運算符
43 
44     # 更新屏幕
45     pygame.display.update()                                         
46     
47     # 處理游戲退出
48     # 從消息隊列中循環取
49     for event in pygame.event.get():
50         if event.type == pygame.QUIT:
51             pygame.quit()
52             exit()
53 
54         # Python中沒有switch-case 多用字典類型替代
55         # 控制方向 == new add ==          
56         if event.type == pygame.KEYDOWN:
57             if event.key in offset:
58                 offset[event.key] = 3
59         elif event.type == pygame.KEYUP:
60             if event.key in offset:
61                 offset[event.key] = 0
62 
63         # part 1
64         #offset_x = offset[pygame.K_RIGHT] - offset[pygame.K_LEFT]
65         #offset_y = offset[pygame.K_DOWN] - offset[pygame.K_UP]
66         #hero_pos = [hero_pos[0] + offset_x, hero_pos[1] + offset_y]
67     # part 2
68     offset_x = offset[pygame.K_RIGHT] - offset[pygame.K_LEFT]
69     offset_y = offset[pygame.K_DOWN] - offset[pygame.K_UP]
70     hero_pos = [hero_pos[0] + offset_x, hero_pos[1] + offset_y]
71     # 控制方向 == new add ==          

新加入了兩處,一個是字典類型的變量,一個是控制方向的代碼。跟之前控制程序退出的代碼一樣,依然是從事件隊列中取事件;當event.type為按鍵事件時,再判斷event.key是否屬于上下左右四個鍵位中的其中一個;最后在其相應方向上給一個偏移量,即完成判斷的過程;松鍵的話該方向上的偏移量賦值為0,這樣該鍵方向上就沒有位移了;最后將偏移量加到飛機的pos上,下一輪刷新時自然就到移動到新地方了。(這里插播一個事,我以前寫過c++和java,所以寫到判斷鍵盤鍵位時,很自然就想用switch-case語句,沒想到竟然出錯了(╯°口°)╯(┴—┴,后來才發現原來Python是沒有switch-case語句的,switch-case語句多用字典數據結構代替,感覺這樣的寫法就更靈活了)

上面講得都比較簡單,現在我們要思考一個問題,上面的代碼中,line 63-66和line 67-70的代碼是一樣的,但兩部分代碼的效果卻是很不一樣。part1代碼使得我們要按一次鍵飛機才會動一次,而在part2代碼中我們可以長按方向鍵來控制飛機,不禁感慨一下Python的縮進。part1是在for循環的影響下的,也就是說,事件隊列中有事件才會執行part1的代碼,假設我們長按方向左鍵(注意,擊鍵一次只會產生一個pygame.KEYDOWN事件,所以長按也只觸發一次),飛機也只會往左移3個像素點;而part2代碼由于不在for循環內,所以每一tick就向左移3個像素點直到松開方向左鍵。

演示一下效果:

好的,控制飛機已經不成問題了,不過大家發現飛機有一個小問題了嗎?它會穿到窗口的“外面”去!不過我們只要添加一個小小的限制就可以解決問題了,只要把line68-70換成以下邊界判斷代碼就可以了。

 1     hero_x = hero_pos[0] + offset[pygame.K_RIGHT] - offset[pygame.K_LEFT]
 2     hero_y = hero_pos[1] + offset[pygame.K_DOWN] - offset[pygame.K_UP]
 3     if hero_x < 0:
 4         hero_pos[0] = 0
 5     elif hero_x > SCREEN_WIDTH - hero1_rect.width:
 6         hero_pos[0] = SCREEN_WIDTH - hero1_rect.width
 7     else:
 8         hero_pos[0] = hero_x
 9         
10     if hero_y < 0:
11         hero_pos[1] = 0
12     elif hero_y > SCREEN_HEIGHT - hero1_rect.height:
13         hero_pos[1] = SCREEN_HEIGHT - hero1_rect.height
14     else:
15         hero_pos[1] = hero_y

今天功能就完成到這里吧~(`?ω?′)

?

轉載于:https://www.cnblogs.com/wuzhanpeng/p/4264267.html

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

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

相關文章

C++字符輸入getchar()和字符輸出putchar()

轉載&#xff1a;http://c.biancheng.net/cpp/biancheng/view/117.html C還保留了C語言中用于輸入和輸出單個字符的函數&#xff0c;使用很方便。其中最常用的有getchar函數和putchar函數。 putchar函數(字符輸出函數) putchar函數的作用是向終端輸出一個字符。例如&#xf…

linux實現shell,linux

4.5Mhttp://www.starbase-929.net/media/Calibre%20Library/Ken%20O.%20Bartch/Linux%20Shell%20Scription%20With%20Bash%20(1778)/Linux%20Shell%20Scription%20With%20Bash%20-%20Ken%20O.%20Bartch.pdfstarbase-929.net全網免費4.0Mhttp://www.myaitcampus.net/elibrary/im…

AQS淺析

2019獨角獸企業重金招聘Python工程師標準>>> AQS的原理淺析 本文是《Java特種兵》的樣章&#xff0c;本書即將由工業出版社出版 AQS的全稱為&#xff08;AbstractQueuedSynchronizer&#xff09;&#xff0c;這個類也是在java.util.concurrent.locks下面。這個類似乎…

str045漏洞提權linux,Linux運維知識之CVE-2016-5195 Dirtycow: Linux內核提權漏洞

本文主要向大家介Linux運維知識之CVE-2016-5195 Dirtycow&#xff1a; Linux內核提權漏洞紹了&#xff0c;通過具體的內容向大家展現&#xff0c;希望對大家學習Linux運維知識有所幫助。CVE-2016-5195 Dirtycow&#xff1a; Linux內核提權漏洞以下都是github上找的源碼&#xf…

編程如寫作

昨晚似乎是個適合寫作的夜&#xff0c;不論是自己還是朋友&#xff0c;都比平常更容易被觸動。看著微博上朋友們的心路&#xff0c;想寫點什么卻似乎找不出非常值得大書特書的主題&#xff0c;只是歪坐在電腦旁&#xff0c;喝著咖啡&#xff0c;單曲循環著倉木麻衣的《time aft…

C++中cin、cin.get()、cin.getline()、getline()等函數的用法

轉載&#xff1a;http://www.cnblogs.com/flatfoosie/archive/2010/12/22/1914055.html c輸入流函數主要以下幾個&#xff1a; 1、cin 2、cin.get() 3、cin.getline() 4、getline() 附:cin.ignore();cin.get()//跳過一個字符,例如不想要的回車,空格等字符 1、cin>>…

工作環境總結(1)開發環境搭建

1、安裝git 安裝文件&#xff1a;Git-2.12.0-64-bit.exe 下載地址&#xff1a;https://github.com/git-for-windows/git/releases/download/v2.12.0.windows.1/Git-2.12.0-64-bit.exe 在git bash中配置&#xff0c;git bash命令行中執行&#xff08;只有使用到egit時使用&…

c語言煙花百度云,C語言實現放煙花的程序

這是一個利用C語言編寫放煙花的程序(同時也可以播放音樂)&#xff0c;供大家參考&#xff0c;具體內容如下代碼如下#pragma once#include#include //圖形界面庫頭文件#include //計算圓形的軌跡坐標#include#include#include#include#pragma comment(lib,"winmm.lib"…

決定人生的七條公式

1 .積跬步以致千里&#xff0c;積怠惰以致深淵 1.01^365 37.80.99^365 0.032.拖延癥 U EV/ID U完成任務的程度 E對成功的信心 V 對任務的愉悅度 I 你的分心程度 D你多久會獲得回報3.三天打魚兩天曬網&#xff0c;終將一無所獲 1.01^3 x 0.99^2 < 1.01 4.愛因斯坦的成…

strncpy與strcpy的區別與注意事項

strncpy 是 C語言的庫函數之一&#xff0c;來自 C語言標準庫&#xff0c;定義于 string.h&#xff0c;char *strncpy(char *dest, char *src, int n)&#xff0c;把src所指字符串的前n個字節復制到dest所指的數組中&#xff0c;并返回指向dest的指針。 strcpy只是復制字符串&am…

使用ssh公鑰實現免密碼登錄

ssh 無密碼登錄要使用公鑰與私鑰。linux下可以用用ssh-keygen生成公鑰/私鑰對&#xff0c;下面我以CentOS為例。 有機器A(192.168.1.155)&#xff0c;B(192.168.1.181)。現想A通過ssh免密碼登錄到B。 首先以root賬戶登陸為例。 1.在A機下生成公鑰/私鑰對。 [rootA ~]# ssh-keyg…

15款的視頻處理軟件免費下載

因為需要購買昂貴的視頻處理軟件和高性能圖形計算機&#xff0c;所以視頻處理是一項比較耗費金錢的技術活。正是由于這樣&#xff0c;一部分人選擇使用性能較好的免費在線編輯軟件&#xff0c;無需太多視頻處理知識便可在瀏覽器中剪切和編輯視頻。然而&#xff0c;當我們無法連…

液位系統c語言程序,超聲波自動測量物體液位系統的設計

超聲波自動測量物體液位系統的設計(任務書,畢業論文15000字)摘要本系統以STC89C52單片機為核心&#xff0c;通過硬件電路連接和軟件程序的編寫實現通用型超聲波自動測量物體液位系統的設計。其主要原理是由單片機控制超聲波發射電路發射超聲波&#xff0c;超聲波接收電路接收遇…

android-sdk-windows版本號下載

Android SDK 4.0.3 開發環境配置及執行 近期又裝了一次最新版本號的ADK環境 眼下最新版是Android SDK 4.0.3 本文的插圖和文本盡管是Android2.2的 步驟都是一樣的&#xff0c;假設安裝的過程中遇到什么問題&#xff0c;能夠留言&#xff0c;我會盡快回復&#xff01; 系統環境的…

string中c_str()、data()、copy(p,n)函數的用法

轉載&#xff1a;http://www.cnblogs.com/qlwy/archive/2012/03/25/2416937.html 標準庫的string類提供了3個成員函數來從一個string得到c類型的字符數組&#xff1a;c_str()、data()、copy(p,n)。 1. c_str()&#xff1a;生成一個const char*指針&#xff0c;指向以空字符終止…

POJ2402 Palindrome Numbers 回文數

題目鏈接: http://poj.org/problem?id2402 題目大意就是讓你找到第n個回文數是什么. 第一個思路當然是一個一個地構造回文數直到找到第n個回文數為止(也許大部分人一開始都是這樣的思路). 很明顯找到第n個之前的所有操作都是浪費, 這也是這個方法的最大弱點. 抱著僥幸心理(誰知…

離散卷積的c語言編程實驗,數字信號處理實驗一離散卷積c語言編程.ppt

數字信號處理實驗一離散卷積c語言編程實驗一 離散卷積的C語言編程實驗 DSP實驗室 2005 實驗性質 綜合設計性實驗 實驗目的 1 了解和認識常用的各種信號&#xff1b; 2 掌握卷積的定義和計算方法&#xff1b; 3 掌握在計算機中生成以及繪制信號序列圖的方法。 實驗原理 離散時間…

async-await原理解析

在用async包裹的方法體中&#xff0c;可以使用await關鍵字以同步的方式編寫異步調用的代碼。那么它的內部實現原理是什么樣的呢&#xff1f;我們是否可以自定義await以實現定制性的需求呢&#xff1f;先來看一個簡單的例子&#xff1a; 1 class Test {2 public sta…

emacs-w3m查看html幫助手冊

<?xml version"1.0" encoding"utf-8"?> emacs-w3m查看html幫助手冊emacs-w3m查看html幫助手冊 Table of Contents 1. 使用效果2. 為什么要用emacs-w3m來查看html的幫助手冊&#xff1f;3. 什么是w3m?4. 配置5. 額外資源1 使用效果 使用快捷鍵C-c …

c語言生命游戲代碼大全,c++生命游戲源碼

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓glViewport( 0, 0, width, height );glMatrixMode( GL_PROJECTION );glLoadIdentity( );}//程序入口int main(int argc, char *argv[]){//隨機生成細胞的狀態MapRand();std::cout<//SDL初始化const SDL_VideoInfo* info NULL;i…