电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Python 實現平臺類游戲添加跳躍功能

瀏覽:158日期:2022-08-01 08:24:25

在本期使用 Python Pygame 模塊編寫視頻游戲中,學會如何使用跳躍來對抗重力。

在本系列的前一篇文章 中,你已經模擬了重力。但現在,你需要賦予你的角色跳躍的能力來對抗重力。

跳躍是對重力作用的暫時延緩。在這一小段時間里,你是向上跳,而不是被重力拉著向下落。但你一旦到達了跳躍的最高點,重力就會重新發揮作用,將你拉回地面。

在代碼中,這種變化被表示為變量。首先,你需要為玩家精靈建立一個變量,使得 Python 能夠跟蹤該精靈是否正在跳躍中。一旦玩家精靈開始跳躍,他就會再次受到重力的作用,并被拉回最近的物體。

設置跳躍狀態變量

你需要為你的 Player 類添加兩個新變量:

一個是為了跟蹤你的角色是否正在跳躍中,可通過你的玩家精靈是否站在堅實的地面來確定 一個是為了將玩家帶回地面

將如下兩個變量添加到你的 Player 類中。在下方的代碼中,注釋前的部分用于提示上下文,因此只需要添加最后兩行:

self.movex = 0 self.movey = 0 self.frame = 0 self.health = 10 # 此處是重力相關變量 self.collide_delta = 0 self.jump_delta = 6

第一個變量 collide_delta 被設為 0 是因為在正常狀態下,玩家精靈沒有處在跳躍中的狀態。另一個變量 jump_delta 被設為 6,是為了防止精靈在第一次進入游戲世界時就發生反彈(實際上就是跳躍)。當你完成了本篇文章的示例,嘗試把該變量設為 0 看看會發生什么。

跳躍中的碰撞

如果你是跳到一個蹦床上,那你的跳躍一定非常優美。但是如果你是跳向一面墻會發生什么呢?(千萬不要去嘗試!)不管你的起跳多么令人印象深刻,當你撞到比你更大更硬的物體時,你都會立馬停下。(LCTT 譯注:原理參考動量守恒定律)

為了在你的視頻游戲中模擬這一點,你需要在你的玩家精靈與地面等東西發生碰撞時,將 self.collide_delta 變量設為 0。如果你的 self.collide_delta 不是 0 而是其它的什么值,那么你的玩家就會發生跳躍,并且當你的玩家與墻或者地面發生碰撞時無法跳躍。

在你的 Player 類的 update 方法中,將地面碰撞相關代碼塊修改為如下所示:

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 # 停止跳躍 if self.rect.y > g.rect.y: self.health -=1 print(self.health)

這段代碼塊檢查了地面精靈和玩家精靈之間發生的碰撞。當發生碰撞時,它會將玩家 Y 方向的坐標值設置為游戲窗口的高度減去一個瓷磚的高度再減去另一個瓷磚的高度。以此保證了玩家精靈是站在地面上,而不是嵌在地面里。同時它也將 self.collide_delta 設為 0,使得程序能夠知道玩家未處在跳躍中。除此之外,它將 self.movey 設為 0,使得程序能夠知道玩家當前未受到重力的牽引作用(這是游戲物理引擎的奇怪之處,一旦玩家落地,也就沒有必要繼續將玩家拉向地面)。

此處 if 語句用來檢測玩家是否已經落到地面之下,如果是,那就扣除一點生命值作為懲罰。此處假定了你希望當你的玩家落到地圖之外時失去生命值。這個設定不是必需的,它只是平臺類游戲的一種慣例。更有可能的是,你希望這個事件能夠觸發另一些事件,或者說是一種能夠讓你的現實世界玩家沉迷于讓精靈掉到屏幕之外的東西。一種簡單的恢復方式是在玩家精靈掉落到地圖之外時,將 self.rect.y 重新設置為 0,這樣它就會在地圖上方重新生成,并落到堅實的地面上。

撞向地面

模擬的重力使你玩家的 Y 坐標不斷增大(LCTT 譯注:此處原文中為 0,但在 Pygame 中越靠下方 Y 坐標應越大)。要實現跳躍,完成如下代碼使你的玩家精靈離開地面,飛向空中。

在你的 Player 類的 update 方法中,添加如下代碼來暫時延緩重力的作用:

if self.collide_delta < 6 and self.jump_delta < 6: self.jump_delta = 6*2 self.movey -= 33 # 跳躍的高度 self.collide_delta += 6 self.jump_delta += 6

根據此代碼所示,跳躍使玩家精靈向空中移動了 33 個像素。此處是負 33 是因為在 Pygame 中,越小的數代表距離屏幕頂端越近。

不過此事件視條件而定,只有當 self.collide_delta 小于 6(缺省值定義在你 Player 類的 init 方法中)并且 self.jump_delta 也于 6 的時候才會發生。此條件能夠保證直到玩家碰到一個平臺,才能觸發另一次跳躍。換言之,它能夠阻止空中二段跳。

在某些特殊條件下,你可能不想阻止空中二段跳,或者說你允許玩家進行空中二段跳。舉個栗子,如果玩家獲得了某個戰利品,那么在他被敵人攻擊到之前,都能夠擁有空中二段跳的能力。

當你完成本篇文章中的示例,嘗試將 self.collide_delta 和 self.jump_delta 設置為 0,從而獲得百分之百的幾率觸發空中二段跳。

在平臺上著陸

目前你已經定義了在玩家精靈摔落地面時的抵抗重力條件,但此時你的游戲代碼仍保持平臺與地面置于不同的列表中(就像本文中做的很多其他選擇一樣,這個設定并不是必需的,你可以嘗試將地面作為另一種平臺)。為了允許玩家精靈站在平臺之上,你必須像檢測地面碰撞一樣,檢測玩家精靈與平臺精靈之間的碰撞。將如下代碼放于你的 update 方法中:

plat_hit_list = pygame.sprite.spritecollide(self, plat_list, False) for p in plat_hit_list: self.collide_delta = 0 # 跳躍結束 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

此處 if 語句代碼塊的第一個子句阻止玩家精靈從平臺正下方跳到平臺上。如果它檢測到玩家精靈的坐標比平臺更大(在 Pygame 中,坐標更大意味著在屏幕的更下方),那么將玩家精靈新的 Y 坐標設置為當前平臺的 Y 坐標加上一個瓷磚的高度。實際效果就是保證玩家精靈距離平臺一個瓷磚的高度,防止其從下方穿過平臺。

else 子句做了相反的事情。當程序運行到此處時,如果玩家精靈的 Y 坐標不比平臺的更大,意味著玩家精靈是從空中落下(不論是由于玩家剛剛從此處生成,或者是玩家執行了跳躍)。在這種情況下,玩家精靈的 Y 坐標被設為平臺的 Y 坐標減去一個瓷磚的高度(切記,在 Pygame 中更小的 Y 坐標代表在屏幕上的更高處)。這樣就能保證玩家在平臺上,除非他從平臺上跳下來或者走下來。

你也可以嘗試其他的方式來處理玩家與平臺之間的互動。舉個栗子,也許玩家精靈被設定為處在平臺的“前面”,他能夠無障礙地跳躍穿過平臺并站在上面。或者你可以設計一種平臺會減緩而又不完全阻止玩家的跳躍過程。甚至你可以通過將不同平臺分到不同列表中來混合搭配使用。

觸發一次跳躍

目前為此,你的代碼已經模擬了所有必需的跳躍條件,但仍缺少一個跳躍觸發器。你的玩家精靈的 self.jump_delta 初始值被設置為 6,只有當它比 6 小的時候才會觸發更新跳躍的代碼。

為跳躍變量設置一個新的設置方法,在你的 Player 類中創建一個 jump 方法,并將 self.jump_delta 設為小于 6 的值。通過使玩家精靈向空中移動 33 個像素,來暫時減緩重力的作用。

def jump(self,platform_list): self.jump_delta = 0

不管你相信與否,這就是 jump 方法的全部。剩余的部分在 update 方法中,你已經在前面實現了相關代碼。

要使你游戲中的跳躍功能生效,還有最后一件事情要做。如果你想不起來是什么,運行游戲并觀察跳躍是如何生效的。

問題就在于你的主循環中沒有調用 jump 方法。先前你已經為該方法創建了一個按鍵占位符,現在,跳躍鍵所做的就是將 jump 打印到終端。

調用 jump 方法

在你的主循環中,將上方向鍵的效果從打印一條調試語句,改為調用 jump 方法。

注意此處,與 update 方法類似,jump 方法也需要檢測碰撞,因此你需要告訴它使用哪個 plat_list。

if event.key == pygame.K_UP or event.key == ord(’w’): player.jump(plat_list)

如果你傾向于使用空格鍵作為跳躍鍵,使用 pygame.K_SPACE 替代 pygame.K_UP 作為按鍵。另一種選擇,你可以同時使用兩種方式(使用單獨的 if 語句),給玩家多一種選擇。

現在來嘗試你的游戲吧!在下一篇文章中,你將讓你的游戲卷動起來。

Python 實現平臺類游戲添加跳躍功能

以下是目前為止的所有代碼:

#!/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# 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 os’’’Objects’’’class Platform(pygame.sprite.Sprite): # x 坐標,y 坐標,圖像寬度,圖像高度,圖像文件 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 = xlocclass Player(pygame.sprite.Sprite): ’’’ 生成一個玩家 ’’’ def __init__(self): pygame.sprite.Sprite.__init__(self) self.movex = 0 self.movey = 0 self.frame = 0 self.health = 10 self.collide_delta = 0 self.jump_delta = 6 self.score = 1 self.images = [] for i in range(1,9): img = pygame.image.load(os.path.join(’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): ’’’ 控制玩家移動 ’’’ self.movex += x self.movey += y def update(self): ’’’ 更新精靈位置 ’’’ self.rect.x = self.rect.x + self.movex self.rect.y = self.rect.y + self.movey # 向左移動 if self.movex < 0: self.frame += 1 if self.frame > ani*3: self.frame = 0 self.image = self.images[self.frame//ani] # 向右移動 if self.movex > 0: self.frame += 1 if self.frame > ani*3: self.frame = 0 self.image = self.images[(self.frame//ani)+4] # 碰撞 enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False) for enemy in enemy_hit_list: self.health -= 1 #print(self.health) plat_hit_list = pygame.sprite.spritecollide(self, plat_list, False) for p in 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): ’’’ 生成一個敵人 ’’’ 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): ’’’ 敵人移動 ’’’ distance = 80 speed = 8 self.movey += 3.2 if self.counter >= 0 and self.counter <= distance: self.rect.x += speed elif self.counter >= distance and self.counter <= distance*2: self.rect.x -= speed else: self.counter = 0 self.counter += 1 if not self.rect.y >= 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’) # 生成敵人 enemy_list = pygame.sprite.Group() # 創建敵人組 enemy_list.add(enemy) # 將敵人添加到敵人組 if lvl == 2: print('Level ' + str(lvl) ) return enemy_list def loot(lvl,lloc): print(lvl) def ground(lvl,gloc,tx,ty): ground_list = pygame.sprite.Group() i=0 if lvl == 1: while i < len(gloc): ground = Platform(gloc[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 = [] i=0 if lvl == 1: ploc.append((0,worldy-ty-128,3)) ploc.append((300,worldy-ty-256,3)) ploc.append((500,worldy-ty-128,4)) while i < len(ploc): j=0 while j <= ploc[i][2]: plat = Platform((ploc[i][0]+(j*tx)),ploc[i][1],tx,ty,’ground.png’) plat_list.add(plat) j=j+1 print(’run’ + str(i) + str(ploc[i])) i=i+1 if lvl == 2: print('Level ' + str(lvl) ) return plat_list’’’Setup’’’worldx = 960worldy = 720fps = 40 # 幀率ani = 4 # 動畫循環clock = pygame.time.Clock()pygame.init()main = TrueBLUE = (25,25,200)BLACK = (23,23,23 )WHITE = (254,254,254)ALPHA = (0,255,0)world = pygame.display.set_mode([worldx,worldy])backdrop = pygame.image.load(os.path.join(’images’,’stage.png’)).convert()backdropbox = world.get_rect()player = Player() # 生成玩家player.rect.x = 0player.rect.y = 0player_list = pygame.sprite.Group()player_list.add(player)steps = 10 # how fast to movejump = -24eloc = []eloc = [200,20]gloc = []#gloc = [0,630,64,630,128,630,192,630,256,630,320,630,384,630]tx = 64 # 瓷磚尺寸ty = 64 # 瓷磚尺寸i=0while i <= (worldx/tx)+tx: gloc.append(i*tx) i=i+1enemy_list = Level.bad( 1, eloc )ground_list = Level.ground( 1,gloc,tx,ty )plat_list = Level.platform( 1,tx,ty )’’’主循環’’’while main == True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit(); sys.exit() main = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT or event.key == ord(’a’): print('LEFT') player.control(-steps,0) if event.key == pygame.K_RIGHT or event.key == ord(’d’): print('RIGHT') player.control(steps,0) if event.key == pygame.K_UP or event.key == ord(’w’): print(’jump’) if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT or event.key == ord(’a’): player.control(steps,0) if event.key == pygame.K_RIGHT or event.key == ord(’d’): player.control(-steps,0) if event.key == pygame.K_UP or event.key == ord(’w’): player.jump(plat_list) if event.key == ord(’q’): pygame.quit() sys.exit() main = False# world.fill(BLACK) world.blit(backdrop, backdropbox) player.gravity() # 檢查重力 player.update() player_list.draw(world) # 刷新玩家位置 enemy_list.draw(world) # 刷新敵人 ground_list.draw(world) # 刷新地面 plat_list.draw(world) # 刷新平臺 for e in enemy_list: e.move() pygame.display.flip() clock.tick(fps)

總結

到此這篇關于Python 實現平臺類游戲添加跳躍功能的文章就介紹到這了,更多相關python 平臺類游戲 跳躍內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 登车桥动力单元-非标液压泵站-非标液压系统-深圳市三好科技有限公司 | 塑胶地板-商用PVC地板-pvc地板革-安耐宝pvc塑胶地板厂家 | 变压器配件,变压器吸湿器,武强县吉口变压器配件有限公司 | 断桥铝破碎机_铝合金破碎机_废铁金属破碎机-河南鑫世昌机械制造有限公司 | 百度网站优化,关键词排名,SEO优化-搜索引擎营销推广 | 电子巡更系统-巡检管理系统-智能巡检【金万码】 | 美名宝起名网-在线宝宝、公司、起名平台 | 打造全球沸石生态圈 - 国投盛世 锂电混合机-新能源混合机-正极材料混料机-高镍,三元材料混料机-负极,包覆混合机-贝尔专业混合混料搅拌机械系统设备厂家 | 环压强度试验机-拉链拉力试验机-上海倾技仪器仪表科技有限公司 | U拓留学雅思一站式服务中心_留学申请_雅思托福培训 | 面粉仓_储酒罐_不锈钢储酒罐厂家-泰安鑫佳机械制造有限公司 | 企业管理培训,企业培训公开课,企业内训课程,企业培训师 - 名课堂企业管理培训网 | 成都离婚律师|成都结婚律师|成都离婚财产分割律师|成都律师-成都离婚律师网 | 合肥风管加工厂-安徽螺旋/不锈钢风管-通风管道加工厂家-安徽风之范 | 氢氧化钾厂家直销批发-济南金昊化工有限公司| 超声波成孔成槽质量检测仪-压浆机-桥梁预应力智能张拉设备-上海硕冠检测设备有限公司 | 体视显微镜_荧光生物显微镜_显微镜报价-微仪光电生命科学显微镜有限公司 | PC构件-PC预制构件-构件设计-建筑预制构件-PC构件厂-锦萧新材料科技(浙江)股份有限公司 | 水成膜泡沫灭火剂_氟蛋白泡沫液_河南新乡骏华消防科技厂家 | 登车桥动力单元-非标液压泵站-非标液压系统-深圳市三好科技有限公司 | 拉力测试机|材料拉伸试验机|电子拉力机价格|万能试验机厂家|苏州皖仪实验仪器有限公司 | 春腾云财 - 为企业提供专业财税咨询、代理记账服务 | 电动葫芦|手拉葫芦|环链电动葫芦|微型电动葫芦-北京市凌鹰起重机械有限公司 | 扬子叉车厂家_升降平台_电动搬运车|堆高车-扬子仓储叉车官网 | 江西自考网-江西自学考试网| 环球电气之家-中国专业电气电子产品行业服务网站! | 首页-瓜尔胶系列-化工单体系列-油田压裂助剂-瓜尔胶厂家-山东广浦生物科技有限公司 | 12cr1mov无缝钢管切割-15crmog无缝钢管切割-40cr无缝钢管切割-42crmo无缝钢管切割-Q345B无缝钢管切割-45#无缝钢管切割 - 聊城宽达钢管有限公司 | 防火阀、排烟防火阀、电动防火阀产品生产销售商-德州凯亿空调设备有限公司 | 科箭WMS仓库管理软件-TMS物流管理系统-科箭SaaS云服务 | 干式磁选机_湿式磁选机_粉体除铁器-潍坊国铭矿山设备有限公司 | 共享雨伞_共享童车_共享轮椅_共享陪护床-共享产品的领先者_有伞科技 | 智能气瓶柜(大型气瓶储存柜)百科 | 【MBA备考网】-2024年工商管理硕士MBA院校/报考条件/培训/考试科目/提前面试/考试/学费-MBA备考网 | 山东PE给水管厂家,山东双壁波纹管,山东钢带增强波纹管,山东PE穿线管,山东PE农田灌溉管,山东MPP电力保护套管-山东德诺塑业有限公司 | 帽子厂家_帽子工厂_帽子定做_义乌帽厂_帽厂_制帽厂_帽子厂_浙江高普制帽厂 | 高压管道冲洗清洗机_液压剪叉式升降机平台厂家-林君机电 | 爱佩恒温恒湿测试箱|高低温实验箱|高低温冲击试验箱|冷热冲击试验箱-您身边的模拟环境试验设备技术专家-合作热线:400-6727-800-广东爱佩试验设备有限公司 | 污泥烘干机-低温干化机-工业污泥烘干设备厂家-焦作市真节能环保设备科技有限公司 | 精密模具-双色注塑模具加工-深圳铭洋宇通| 空心明胶胶囊|植物胶囊|清真胶囊|浙江绿键胶囊有限公司欢迎您! |