日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Pygame游戏飞机大战《星野守望》

發(fā)布時間:2023/12/29 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Pygame游戏飞机大战《星野守望》 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

程序地址:網(wǎng)頁鏈接

注意:目前只支持win系統(tǒng)。

游戲做的不完整,只能用來體驗(yàn)體驗(yàn)。

最近接觸了Pygame游戲編程,十分感興趣,學(xué)習(xí)了一本相關(guān)書籍以及查閱了Pygame的官網(wǎng)https://www.pygame.org的資料,花了一周的時間寫出了這個飛機(jī)大戰(zhàn)的游戲。主體玩法相對完整,模擬的是逝去的手游帝王《雷霆戰(zhàn)機(jī)》,算是對它多舛命運(yùn)的哀悼吧。

話不多說,先看效果

什么,你問我素材哪里找的?萬能的淘寶在這時候總不會讓你失望!所有音頻和圖片素材均來自于淘寶。

這里跟大家分享幾個制作過程中遇到的幾個技術(shù)細(xì)節(jié)的解決方法,以及優(yōu)化措施:

1.幀率不同步問題。

我用pygame.time.Clock對象來控制整個游戲的最大幀率為60。為什么說是最大呢?不是因?yàn)樾阅茉驅(qū)е掠螒驇收娴牡陀?0(雖然在某些過程優(yōu)化之前的確出現(xiàn)過卡的低于60幀的情況),是因?yàn)槟承﹦赢嬤^程的幀率本就不是60,比如飛機(jī)爆炸的動畫,就那么9幀,若60Hz播放的話就顯得太快了,起初,我想到用重復(fù)的圖片Surface對象填充這些應(yīng)該重復(fù)的幾幀,使得切換到下一幀的速度沒那么快,但重復(fù)的圖片對象會導(dǎo)致成倍數(shù)的內(nèi)存占用,這是我不能忍受的。于是我用了一個FramNum對象,將重復(fù)的次數(shù)用正整數(shù)num表示,并增加計數(shù)點(diǎn)屬性,當(dāng)運(yùn)行到下一次就增加一個計數(shù)點(diǎn),若計數(shù)點(diǎn)達(dá)到了num,則運(yùn)行下一幀。于是一個完整的動畫幀F(xiàn)rame對象被設(shè)計成由FramNum對象組成,能夠成倍數(shù)地減少在動畫幀方面內(nèi)存使用。

以下實(shí)現(xiàn)代碼看不懂沒關(guān)系,因?yàn)樽⑨尣磺宄?#xff0c;而且有一些額外的設(shè)計沒有被提及。

import pygameclass FrameNum:def __init__(self, frame:pygame.Surface, num:int):self.frame = frameself.num = numdef __getframe(self):return self.__framedef __setframe(self, other):self.__frame = otherframe = property(__getframe, __setframe)def __getnum(self):return self.__numdef __setnum(self, other):self.__num = othernum = property(__getnum, __setnum)def __mul__(self, other):self.num *= otherreturn selfdef __imul__(self, other):self.num *= otherreturn selfdef __getitem__(self, item):if item == 0:return self.frameelif item == 1:return self.numelse:raise ValueError('indexvalue not 0 or 1!')class Frame:'like [[(frame1,num1),(frame2,num2)],[...]]'LASTCIRCLE= b'\x01'LASTSTICK = b'\x00'def __init__(self, framelist, leisureframe=0):self.framelist = framelist# this conditionself.this_code = leisureframeself.thiscondition = framelist[self.this_code]# this condition lenself.thiscdlen = len(self.thiscondition)# this frameself.thisframe = 0# this frame numself.thisfnum = self.thiscondition[self.thisframe][1]self.thisgone = 0self.image = self.thiscondition[self.thisframe][0]self.next_code = self.LASTCIRCLEself.sticked = False# 得到本狀態(tài)的虛擬幀數(shù)目self.leisureframe = leisureframedef set_stick(self):self.next_code = self.LASTSTICKdef unsetonce(self):self.next_code = self.LASTCIRCLEdef update(self):# 若為循環(huán)播放if not self.sticked:if self.next_code == self.LASTCIRCLE:self.circleupdate()elif self.next_code == self.LASTSTICK:self.stickupdate()else:self.onceupdate()def changecondition(self, condition_code):self.thiscondition = self.framelist[condition_code]self.thisgone = 0self.thisframe = 0self.this_code = condition_codeself.thiscdlen = len(self.thiscondition)self.updateframe()# 跳轉(zhuǎn)condition代碼def set_next(self, next_code):self.next_code = next_codedef set_condition(self, this_code):self.this_code = this_codedef circleupdate(self):# 若達(dá)到這一幀的最后一個if self.thisgone >= self.thisfnum:# 進(jìn)入下一幀self.nextframe()# 若超過最后一幀if self.thisframe >= self.thiscdlen:self.thisframe = 0self.thisgone = 0# 圖像變化self.updateframe()# 下一個虛幀self.go()def stickupdate(self):if self.thisframe < self.thiscdlen - 1:if self.thisgone >= self.thisfnum - 1:self.nextframe()self.updateframe()else:self.go()elif self.thisframe == self.thiscdlen - 1:if self.thisgone < self.thisfnum - 1:self.go()else:if not self.sticked:self.sticked = Truedef onceupdate(self):if not self.thisframe == self.next_code:if self.thisframe < self.thiscdlen - 1:if self.thisgone >= self.thisfnum:self.nextframe()self.updateframe()self.go()else:if self.thisgone >= self.thisfnum:self.changecondition(self.next_code)else:self.go()def set_certain(self, new_thisframe, new_condition_code, sticked=False):self.this_code = new_condition_codeself.thisframe = new_thisframeself.thiscondition = self.framelist[self.this_code]self.updateframe()self.thiscdlen = len(self.thiscondition)self.thisgone = 0self.next_code = self.LASTSTICK if sticked else self.LASTCIRCLEself.sticked = Falsedef nextframe(self):self.thisgone = 0self.thisframe += 1def updateframe(self):self.image = self.thiscondition[self.thisframe][0]self.thisfnum = self.thiscondition[self.thisframe][1]def go(self):self.thisgone += 1def copy(self):return Frame(self.framelist, self.leisureframe)

2.按鈕制作

按鈕是和鼠標(biāo)放上和鼠標(biāo)點(diǎn)擊時間交互的精靈對象,我用兩個旗幟onCovered和onClicked來保存鼠標(biāo)放上和點(diǎn)擊按鈕的狀態(tài),并且鼠標(biāo)放上將使按鈕變得更亮,移開后按鈕又恢復(fù)原狀。點(diǎn)擊按鈕又是另一種動畫幀。有了以上Frame對象管理幀,這個整體變得不難實(shí)現(xiàn)。

3.游戲開始前的背景

游戲開始前的背景是用29幀動畫重復(fù)播放實(shí)現(xiàn)的

4.游戲背景循環(huán)滾動設(shè)計

正式進(jìn)入游戲,希望能模擬飛機(jī)戰(zhàn)場的推進(jìn),背景向下方不斷滾動,并循環(huán)播放,此代碼保證一次最多只渲染兩個背景圖片,當(dāng)滾動出界時回到原處重復(fù)過程,能做到無縫銜接

最終游戲背景為如下VerticalUSBG對象

import pygame from myGametools import mySprite from myGametools import mypointclass BackGround(mySprite.MyMoveSprite):def draw(self, screen:pygame.Surface):screen.blit(self.image, self.rect)self.update()class UnStopBG(BackGround):def __init__(self, frame, position:mypoint.Mypoint, speed=0, accelerate=0):self.frame = frameself.image = self.frame.imageself.rect = pygame.Rect(*position.position, *self.image.get_size())self.speed = speedself.accelerate = accelerateclass LevelUSBG(UnStopBG):def draw(self, screen:pygame.Surface):lastrect = self.rectfor i in range(screen.get_width()//self.rect.width + 1):screen.blit(self.image, lastrect)lastrect.topleft = lastrect.toprightif self.speed > 0:if 0 < self.rect.left < self.rect.width:screen.blit(self.image, (self.rect.left-self.rect.width, self.rect.top))elif self.rect.left >= self.rect.width:self.rect.left = 0elif self.speed < 0:if lastrect.left <= screen.get_width():screen.blit(self.image, lastrect)if self.rect.right <= 0:self.rect.left = 0else:returnself.rect = self.rect.move(self.speed, 0)self.speed += self.accelerateclass VerticalUSBG(UnStopBG):def draw(self, screen: pygame.Surface):lastrect = self.rect.copy()for i in range(screen.get_height() // self.rect.height + 1):screen.blit(self.image, lastrect)lastrect.topleft = lastrect.bottomleftif self.speed > 0:if 0 < self.rect.top < self.rect.height:screen.blit(self.image, (self.rect.left, self.rect.top-self.rect.height, self.rect.width, self.rect.height))elif self.rect.top >= self.rect.height:self.rect.top = 0elif self.speed < 0:if lastrect.bottom <= screen.get_height():screen.blit(self.image, lastrect)if self.rect.bottom <= 0:self.rect.top = 0else:returnself.rect = self.rect.move(0, self.speed)self.speed += self.accelerate

5.玩家飛機(jī)操縱邏輯和飛機(jī)姿態(tài)轉(zhuǎn)換邏輯

玩家飛機(jī)控制的最開始版本為飛機(jī)只有一個正面的姿態(tài),沒有側(cè)翻的姿態(tài),并且飛機(jī)不能加速,只能勻速運(yùn)動,控制鍵為"wasd"系(w向前,a向左,s向后,d向右)

但這樣玩起來十分枯燥,手感單一。于是想到模擬飛機(jī)控制的實(shí)際情景,為飛機(jī)添加加速度。如當(dāng)玩家按下a時,飛機(jī)就像左加速,當(dāng)玩家松開時,飛機(jī)就減速直到速度為0。而加速有一個最大值。并且要保證飛機(jī)不飛出窗口,由于編寫飛機(jī)的過程中多次涉及到“限制”這個概念,于是想到寫B(tài)ound類系:

import pygameimport sys # bound族都有l(wèi)imit協(xié)議class BoundUnit:NEGATIVE_INFINITY = b'\x11'POSITIVE_INFINITY = b'\x01'def __init__(self, floor=NEGATIVE_INFINITY, ceiling=POSITIVE_INFINITY):self.__floor = floorself.__ceiling = ceilingself.__room = (floor, ceiling)def __getf(self):return self.__floordef __getc(self):return self.__ceilingdef __getroom(self):return self.__roomfloor = property(__getf)ceiling = property(__getc)room = property(__getroom)def floorlimit(self, other, eq=True):if self.floor == self.NEGATIVE_INFINITY:return Trueif eq:return self.floor <= otherelse:return self.floor < otherdef ceilinglimit(self, other, eq=True):if self.ceiling == self.POSITIVE_INFINITY:return Trueif eq:return other <= self.ceilingelse:return other < self.ceilingdef limit(self, other, eqf=True, eqc=True):return self.floorlimit(other, eqf) and self.ceilinglimit(other, eqc)def setin(self, other, eqf=True, eqc=True):if not self.floorlimit(other, eqf):other = self.floorelif not self.ceilinglimit(other,eqc):other = self.ceilingreturn otherdef __getitem__(self, item):return self.room[item]class BoundGroup:# 限制群def __init__(self, *groups):self.bounds = set(groups)def __add__(self, other):return self.bounds + other.boundsdef __radd__(self, other):return self + otherdef __iadd__(self, other):self.bounds += set(other)return selfdef limit(self, other):for i in self.bounds:if not i.limit(other):return Falsereturn Trueclass BoundLine:# 切割數(shù)軸的有序bound# 必須為升序def __init__(self, boundpoints):bounds = []self.boundlen = len(boundpoints) + 1if self.boundlen == 1:bounds.append(BoundUnit(BoundUnit.NEGATIVE_INFINITY, BoundUnit.POSITIVE_INFINITY))else:bounds.append(BoundUnit(BoundUnit.NEGATIVE_INFINITY, boundpoints[0]))for i in range(self.boundlen-2):if not boundpoints[i] < boundpoints[i+1]:raise ValueError('please garantee its ascending order')bounds.append(BoundUnit(boundpoints[i], boundpoints[i+1]))bounds.append(BoundUnit(boundpoints[-1], BoundUnit.POSITIVE_INFINITY))self.bounds = boundsdef detect_section(self, other, righteq=True):for i in range(self.boundlen):if self.bounds[i].limit(other, not righteq, righteq):return iclass BoundLineSymmetry(BoundLine):def __init__(self, boundpoints):bounds = []boundpoints.reverse()negboundpoints = [-i for i in boundpoints]self.lefthalfbounds = BoundLine(negboundpoints)for i in negboundpoints:bounds.append(i)boundpoints.reverse()self.righthalfbounds = BoundLine(boundpoints)if boundpoints[0]:bounds.append(boundpoints[0])for i in boundpoints[1:]:bounds.append(i)super().__init__(bounds)def detect_section(self, other, righteq=True):leftdetect = self.lefthalfbounds.detect_section(other, not righteq)rightdetect = self.righthalfbounds.detect_section(other, righteq)return leftdetect + rightdetectclass Boundlftb:# 目前不支持改變def __init__(self, bound_1: bound.BoundUnit, bound_2: bound.BoundUnit):self.__left = bound_1[0]self.__right = bound_1[1]self.__top = bound_2[0]self.__bottom = bound_2[1]self.__leftright = bound_1.roomself.__topbottom = bound_2.roomself.bound_1 = bound_1self.bound_2 = bound_2self.__bound = (self.bound_1, self.bound_2)def __getl(self):return self.__leftdef __getr(self):return self.__rightdef __gett(self):return self.__topdef __getb(self):return self.__bottomdef __getlr(self):return self.__leftrightdef __gettb(self):return self.__topbottomleft = property(__getl)right = property(__getr)top = property(__gett)bottom = property(__getb)leftright = property(__getlr)topbottom = property(__gettb)def leftlimit(self, other, eq=True):return self.bound_1.floorlimit(other, eq)def rightlimit(self, other, eq=True):return self.bound_1.ceilinglimit(other, eq)def xlimit(self, other, eql=True, eqr=True):return self.bound_1.limit(other, eql, eqr)def toplimit(self, other, eq=True):return self.bound_2.floorlimit(other, eq)def bottomlimit(self, other, eq=True):return self.bound_2.ceilinglimit(other, eq)def ylimit(self, other, eqt=True, eqb=True):return self.bound_2.limit(other, eqt, eqb)def limit(self, x, y, xeqf=True, xeqc=True, yeqf=True, yeqc=True):return self.xlimit(x, xeqf, xeqc) and self.ylimit(y, yeqf, yeqc)def __getitem__(self, item):return self.__bound[item]

總之它們封裝了可用于限制速度和飛機(jī)位置的代碼,并在飛機(jī)的實(shí)現(xiàn)中用到

對于飛機(jī)的姿態(tài)問題也就迎刃而解了,就根據(jù)其向左或向右的速度區(qū)間,利用以上的數(shù)軸對稱區(qū)間劃分BuondLineSemmetry類來判斷飛機(jī)速度所在區(qū)間,并確定將信息返回給飛機(jī),使得飛機(jī)具備相應(yīng)的狀態(tài)stage屬性,在根據(jù)該屬性調(diào)整顯示圖片

6.飛機(jī)發(fā)射武器

武器可以看作子彈的群組,于是從pygame.sprite.Sprite繼承了Bullet子彈類,從pygame.sprite.Group繼承了Gun武器類。武器能間隔一段時間在飛機(jī)的固定的一些相對位置生成子彈,因此武器也需要和飛機(jī)綁定配置在一起。于是飛機(jī)和武器又是has-a關(guān)系。注意到飛機(jī)的組成如此復(fù)雜,為了避免寫出有極多屬性的飛機(jī)類,于是用ControlCenter控制中心類來封裝飛機(jī)的運(yùn)動,并用Engine類封裝飛機(jī)運(yùn)動的控制:

# controlcenter.py import random import pygame from . import engine from classes import bound, boundlrtb from init import constants from init import globalsInitclass ControlCenter:'''manage move and location'''def __init__(self, engine:engine.Engine):# engine only manage speed changing and accelerate changingself.engine = engine# 預(yù)加載screen_bound 免得每次都重復(fù)生成self.space_b = globalsInit.screen_bounddef configure(self, plane):# 初始位置self.plane = planeself.rect = pygame.Rect(int(constants.SCREEN_SIZE[0] / 2 - plane.rect.width),int(constants.BeginLocCEnter - plane.rect.height / 2),plane.rect.width,plane.rect.height)plane.rect = self.rectdef control(self):self.engine.drive()self.updatelocation()self.plane.rect = self.rectdef updatelocation(self):if not self.space_b.leftlimit(self.rect.left, True):self.rect.left = self.space_b.leftelif not self.space_b.rightlimit(self.rect.right, True):self.rect.right = self.space_b.rightif not self.space_b.toplimit(self.rect.top, True):self.rect.top = self.space_b.topelif not self.space_b.bottomlimit(self.rect.bottom, True):self.rect.bottom = self.space_b.bottomself.rect.left += self.engine.speed[0]self.rect.top += self.engine.speed[1]def copy(self):return ControlCenter(self.engine.copy())class Enemy_Controlcenter(ControlCenter):def configure(self, plane):self.plane = planeself.rect = plane.rectclass Sa_1_Controlcenter(Enemy_Controlcenter): # 敵人的中央控制器def control(self):if self.rect.bottom < 0:self.engine.a_acce()else:super().control()# engine.py import pygame, random from pygame.locals import * from myGametools import mymove from classes import boundlrtb, bound from classes.planes import planeclass Engine(mymove.Mymove):# only for speed and accelerate(manally, just for player)# 目前在Engine類中硬編碼所有飛船都應(yīng)遵守的協(xié)議ACCE_x = 1ACCE_y = 0.2ACCE_F = 0.5LEFT = 0LEISURE = 1RIGHT = 2STAGE_P = bound.BoundLineSymmetry([1, 4, 6, 10])(STAGE_LEFT3, STAGE_LEFT2, STAGE_LEFT1,STAGE_LEISURE,STAGE_RIGHT1, STAGE_RIGHT2, STAGE_RIGHT3) = (1, 2, 3,4,5, 6, 7)def __init__(self, speedbound:boundlrtb.Boundlftb, speed=None, accelerate=None):super().__init__(speed, accelerate)self.speed_b = speedboundself.stage = self.STAGE_P.detect_section(self.speed[0])def w_acce(self):if self.speed_b.ylimit(self.speed[1]):if self.speed[1] > 0:self.setyAccelerate(-(self.ACCE_y + self.ACCE_F))else:self.setyAccelerate(-self.ACCE_y)def a_acce(self):if self.speed_b.xlimit(self.speed[0]):if self.speed[0] > 0:self.setxAccelerate(-(self.ACCE_x + self.ACCE_F))else:self.setxAccelerate(-self.ACCE_x)def s_acce(self):if self.speed_b.ylimit(self.speed[1]):if self.speed[1] < 0:self.setyAccelerate(self.ACCE_y + self.ACCE_F)else:self.setyAccelerate(self.ACCE_y)def d_acce(self):if self.speed_b.xlimit(self.speed[0]):if self.speed[0] < 0:self.setxAccelerate(self.ACCE_x + self.ACCE_F)else:self.setxAccelerate(self.ACCE_x)def drive(self):keys = pygame.key.get_pressed()if keys[K_w] and not keys[K_s]:self.w_acce()elif keys[K_s] and not keys[K_w]:self.s_acce()else:if self.accelerate[1]:self.accelerate[1] = 0if self.speed[1] > 0:self.speed[1] -= self.ACCE_Fif self.speed[1] < 0:self.speed[1] = 0elif self.speed[1] < 0:self.speed[1] += self.ACCE_Fif self.speed[1] > 0:self.speed[1] = 0if keys[K_a] and not keys[K_d]:self.a_acce()elif keys[K_d] and not keys[K_a]:self.d_acce()else:if self.accelerate[0]:self.accelerate[0] = 0if self.speed[0] > 0:self.speed[0] -= self.ACCE_Fif self.speed[0] < 0:self.speed[0] = 0elif self.speed[0] < 0:self.speed[0] += self.ACCE_Fif self.speed[0] > 0:self.speed[0] = 0self.updatespeed()self.updatestage()def updatestage(self):self.stage = self.STAGE_P.detect_section(self.speed[0])def updatespeed(self):self.speed[0] += self.accelerate[0]self.speed[1] += self.accelerate[1]self.speed[0] = self.speed_b.bound_1.setin(self.speed[0])self.speed[1] = self.speed_b.bound_2.setin(self.speed[1])def copy(self):return Engine(self.speed_b, self.speed[:], self.accelerate[:])class Enemy_Engine(mymove.Mymove): # 敵人的引擎def __init__(self):super().__init__()self.last_acce = pygame.time.get_ticks()self.acce_time = self.ACCE_TIMEself.sleep_time = self.SLEEP_TIMEself.sleeping = Falseself.acceing = Falsedef copy(self):return Enemy_Engine()class Sa_1_Engine(Enemy_Engine):ACCE_X = 1ACCE_Y = 0.1ACCE_F = 0.5ACCE_TIME = 300SLEEP_TIME = 100def drive(self):# 睡眠結(jié)束super().updatespeed()if not self.acceing and not self.sleeping:d = random.randint(1, 4)if d == 1:self.w_acce()if d == 2:self.a_acce()if d == 3:self.s_acce()if d == 4:self.d_acce()self.acceing = True# 加速中elif self.acceing and not self.sleeping:now = pygame.time.get_ticks()if now - self.last_acce >= self.ACCE_TIME:self.sleeping = Trueself.acceing = Falseself.accelerate = [0,0]self.last_acce = now# 睡眠中elif self.sleeping:if self.speed[0] > 0:self.speed[0] -= self.ACCE_Fif self.speed[0] < 0:self.speed[0] = 0elif self.speed[0] < 0:self.speed[0] += self.ACCE_Fif self.speed[0] > 0:self.speed[0] = 0if self.speed[1] > 0:self.speed[1] -= self.ACCE_Fif self.speed[1] < 0:self.speed[1] = 0elif self.speed[1] < 0:self.speed[1] += self.ACCE_Fif self.speed[1] > 0:self.speed[1] = 0now = pygame.time.get_ticks()if now - self.last_acce >= self.SLEEP_TIME:self.sleeping = Falseself.last_acce = nowdef w_acce(self):self.accelerate[1] = -self.ACCE_Ydef a_acce(self):self.accelerate[0] = -self.ACCE_Xdef s_acce(self):# can use to drive showself.accelerate[1] = self.ACCE_Ydef d_acce(self):self.accelerate[0] = self.ACCE_Xdef copy(self):return Sa_1_Engine()

這樣,飛機(jī)就只有controlcenter屬性和weapon屬性了

7.敵人飛機(jī)生成

敵人飛機(jī)生成涉及到實(shí)例對象產(chǎn)生的問題,和炮彈生成一樣,用一個群組Group類的子類封裝敵人的每隔一段時間隨機(jī)生成的邏輯。為保證每個敵人完全獨(dú)立,為每個組件都增加了一個copy函數(shù),使之在內(nèi)存中復(fù)制,從而不相互干擾

8.生命值的計算和顯示邏輯。

如果沒有生命值外框,又怎么知道扣了多少生命值呢?于是我設(shè)計了HpFrameBar(繼承自pygame.sprite.Group)來封裝外框和實(shí)條。

用Hp類來封裝數(shù)值的運(yùn)算代碼(很簡單,只有加和減)

玩家生命值條和外框的顯示位置可以硬編碼在左下角,但敵人的生命顯示只能隨敵人位置變化。于是也增加了HpFrameBar于一個敵人實(shí)例的綁定函數(shù)configure,且隨敵人位置移動而移動

由于篇幅限制,沒有討論子彈和飛機(jī)爆炸播放邏輯和音效播放邏輯的實(shí)現(xiàn)。

技術(shù)介紹完。

目前游戲沒有實(shí)現(xiàn)的是游戲結(jié)束邏輯,更豐富的戰(zhàn)斗體驗(yàn)以及游戲進(jìn)度保存。因?yàn)樽罱獙W(xué)JavaScript/HTML/CSS了,所以這個游戲做到這樣能玩就收手了,各位還請海涵。

源代碼:

鏈接: https://pan.baidu.com/s/1SwBsF-bjoBbHkN_LY4Ddqw

提取碼: mnfc?

鏈接永遠(yuǎn)有效,請放心食用!

總結(jié)

以上是生活随笔為你收集整理的Pygame游戏飞机大战《星野守望》的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美超碰在线观看 | 欧美精品国产一区二区 | 干爹你真棒插曲免费 | 国产18页| 欧美四级在线观看 | 亚洲一级av无码毛片精品 | 国产一区二区三区在线看 | 牛牛精品一区二区 | 看全黄大色黄大片 | 1区2区3区视频 | 免费看特级毛片 | 日韩三级成人 | 亚洲无码精品免费 | 久久伊人色 | 中文字幕在线1 | 国产精品99无码一区二区 | 在线污视频 | 这里只有精品视频在线 | 天天色天 | 久久精品国产成人av | jizz国产精品| 亚洲午夜精品久久久久久浪潮 | 先锋av资源网 | 97免费在线视频 | 911久久| 拔插拔插华人 | 手机免费av | 国产免费内射又粗又爽密桃视频 | 欧美日韩二三区 | 欧美区国产区 | 91久久精品www人人做人人爽 | 国产一区免费看 | 欧美亚洲中文精品字幕 | 影音先锋欧美资源 | 亚洲性久久久 | 国产精品一区免费 | 成人毛片在线免费观看 | 日韩欧美aaa | 欧美三日本三级少妇三99 | 深爱激情综合网 | 九一爱爱 | 波多野结衣高清视频 | 色女人网 | 影音先锋在线看片资源 | 哺乳期喷奶水丰满少妇 | 久久大胆视频 | 欧美成人综合色 | 日本动漫艳母 | 国色天香一区二区 | 国产精品你懂得 | 在线观看三区 | 日本99热| 91免费视 | 91综合在线| 国产精品一区二区人人爽 | 成人激情免费 | 黄色高清网站 | 欧美性猛交xxx乱大交3蜜桃 | www.一区二区三区四区 | 手机看片一区二区三区 | 色射射 | 成人乱码一区二区三区 | 男女拍拍拍网站 | 国久久| 深夜福利网站在线观看 | 九九九久久久久 | av有码在线观看 | 欧美日韩加勒比 | 日韩少妇内射免费播放18禁裸乳 | 日韩国产毛片 | 黄色大片91 | 日本中文字幕网站 | 欧美成片vs欧美 | 日韩av一卡 | 草色噜噜噜av在线观看香蕉 | 国产综合久久久久久鬼色 | 国产午夜一级一片免费播放 | 中出 在线| 一区影视 | 国产中文在线播放 | 99精品在线播放 | 成人av视屏 | 无码人妻丰满熟妇区五十路百度 | 色黄啪啪网| 亚洲欧美专区 | 亚洲美女自拍 | 亚洲精选在线观看 | 亚洲国产欧美日韩 | 91精品国产91久久久久久久久久久久 | 伊人天天操 | caopeng视频| 午夜尤物| 日韩亚洲区 | 污视频免费看 | 欧美变态网站 | 老女人一毛片 | 在线视频中文字幕 | 色黄视频网站 | 亚洲区 欧美区 |