日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Python3.7版---双人联机雷霆战机(2D特效+音效+道具+Linux系统)

發布時間:2023/12/29 linux 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python3.7版---双人联机雷霆战机(2D特效+音效+道具+Linux系统) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作品原名稱:MultiplayerGameEngine-master

作者:Tomcat(好像是這個名字沒注意…)

改良者:CSDN阿坤

Hello everyone!
Today ,I will to be give everyone show a game!(英語-2級水平)
今天為大家帶來的是一款雙人游戲并且是2D喲,并且還附帶音效道具等等,游戲環境只需要Python3以及pygame&&numpy即可完美運行,是小編從pygame上挑的一款比較不錯的游戲,初始解包后直接運行雖然各種報錯但是經過小編不辭辛苦的努力終于將其在Linux系統下完美運行!

因為是一款雙人游戲,所以游戲的主文件分為兩個 分別是Player1、Player2

由于兩者內容差不多所以呢在這里只展示Player1完整代碼:

#!/usr/bin/env python3 # -*- coding:utf-8 -*-import osfrom pygame import freetype__author__ = "Yoann Berenguer" __credits__ = ["Yoann Berenguer"] __version__ = "1.0.0" __maintainer__ = "Yoann Berenguer" __email__ = "yoyoberenguer@hotmail.com"import random import socket import _pickle as cpickle import threading import time import copyregtry:import pygame except ImportError:print("\n<Pygame> library is missing on your system.""\nTry: \n C:/pip install pygame on a window command prompt.")raise SystemExittry:import lz4.frame except ImportError:print("\n<lz4> library is missing on your system.""\nTry: \n C:/pip install lz4 on a window command prompt.")raise SystemExittry:from CreateHalo import PlayerHalofrom SoundServer import SoundControlfrom TextureTools import *from NetworkBroadcast import Broadcast, EventAttr, StaticSprite, AnimatedSprite, SoundAttr, BlendSpritefrom Explosions import Explosionfrom LayerModifiedClass import LayeredUpdatesModifiedimport GLOBALfrom GLOBAL import GLfrom ShootingStars import ShootingStarfrom AfterBurners import AfterBurnerfrom End import PlayerLostfrom PlayerScore import DisplayScorefrom CosmicDust import COSMIC_DUST_ARRAY, create_dust, display_dustfrom Gems import MakeGemsfrom LifeBar import HorizontalBarexcept ImportError:print("\nOne or more game libraries is missing on your system.""\nDownload the source code from:\n""https://blog.csdn.net/qq_43417559")raise SystemExit# socket.setdefaulttimeout(0)def unserialize_event(is_set: threading.Event) -> threading.Event:"""Set the internal flag to true. All threads waiting for it to become true are awakened.Return a threading event set to True:param is_set: threading event:return: return a threading event set to true.>>> event_ = threading.Event()>>> u_event = unserialize_event(event_)>>> assert isinstance(u_event, threading.Event)>>> event_.set()>>> event_.isSet()True>>> u_event = unserialize_event(event_)>>> u_event.isSet()True>>> event_.clear()>>> u_event = unserialize_event(event_)>>> u_event.isSet()True"""assert isinstance(is_set, threading.Event), \print("Positional argument <is_set> is type %s , expecting threading.Event." % type(is_set))event_ = threading.Event()if is_set:event_.set()return event_def serialize_event(e: threading.Event) -> tuple:""":param e: threading event:return: <function unserialize_event>, True or False>>> event_ = threading.Event()>>> s = serialize_event(event_)>>> assert isinstance(s, tuple)>>> u, v = list(s)>>> assert isinstance(u, type(unserialize_event))>>> assert v[0] == False>>> event_ = threading.Event()>>> event_.set()>>> s = serialize_event(event_)>>> assert isinstance(s, tuple)>>> u, v = list(s)>>> assert isinstance(u, type(unserialize_event))>>> assert v[0] == True"""assert isinstance(e, threading.Event), \print("Positional argument <e> is type %s , expecting threading.Event." % type(e))return unserialize_event, (e.isSet(),)copyreg.pickle(threading.Event, serialize_event)class LaserImpact(pygame.sprite.Sprite):containers = Noneimages = Nonedef __init__(self, gl_, pos_, parent_, timing_=16, blend_=None, layer_=0):"""Create an impact sprite effect (absorption effect) where the laser is colliding.:param gl_: class GL (contains all the game global variables):param pos_: tuple of the impact position (x:int, y:int):param parent_: parent object (MirroredPlayer1Class class instance):param timing_: integer; refreshing time in milliseconds (default 16ms is 60FPS):param blend_: integer; blend effect to apply to the sprite, default pygame.BLEND_RGB_ADD = 0:param layer_: integer < 0; represent the sprite layer. default = 0"""assert isinstance(pos_, tuple), \"Positional argument <pos_> is type %s , expecting tuple." % type(pos_)assert isinstance(parent_, Asteroid), \"Positional argument <parent_> is type %s , expecting class MirroredPlayer1Class instance." % type(parent_)assert isinstance(timing_, int), \"Positional argument <timing_> is type %s , expecting integer." % type(timing_)if blend_ is None:raise ValueError('Blend should not be unset!')else:assert isinstance(blend_, int), \"Positional argument <blend_> is type %s , expecting integer." % type(blend_)assert isinstance(layer_, int), \"Positional argument <layer_> is type %s , expecting integer." % type(layer_)if self.containers is None:raise ValueError('LaserImpact.containers is not initialised.\nMake sure to assign the containers to'' a pygame group prior instantiation.\ne.g: LaserImpact.containers = ''pygame.sprite.Group()')if self.images is None:raise ValueError("LaserImpact.images is not initialised.\nMake sure to assign a texture to ""prior instantiation.\ne.g: LaserImpact.images = 'P1_SURFACE'")if timing_ < 0:raise ValueError('Positional argument timing_ cannot be < 0')pygame.sprite.Sprite.__init__(self, self.containers)if isinstance(self.containers, pygame.sprite.LayeredUpdates):if layer_:self.containers.change_layer(self, layer_)assert isinstance(self.images, (list, pygame.Surface))self.image = self.images[0] if isinstance(self.images, list) else self.imagesself.rect = self.image.get_rect(center=pos_)self.timing = timing_self.dt = 0self.index = 0self.gl = gl_self.blend = blend_self.layer = layer_self.length = len(self.images) - 1self.parent_ = parent_self.surface_name = 'IMPACT_LASER'self.id_ = id(self)self.impact_object = Broadcast(self.make_object())def make_object(self) -> AnimatedSprite:"""Create an AnimatedSprite message object (see NetworkBroadcast library):return: AnimatedSprite instance"""# Only attributes self.gl.FRAME change, self.rect and self.index are changing over the time.return AnimatedSprite(frame_=self.gl.FRAME, id_=self.id_, surface_=self.surface_name,layer_=self.layer, blend_=self.blend, rect_=self.rect,index_=self.index)def update(self):if self.dt > self.timing:if self.rect.colliderect(self.gl.SCREENRECT):if isinstance(self.images, list):self.image = self.images[self.index % self.length]# follow the parent object with half of its speedself.rect.move_ip(self.parent_.speed // 2)self.index += 1if self.index > self.length:self.kill()self.dt = 0else:self.kill()if self.rect.colliderect(self.gl.SCREENRECT):self.impact_object.update({'frame': self.gl.FRAME, 'rect': self.rect, 'index': self.index})self.impact_object.queue()self.dt += self.gl.TIME_PASSED_SECONDSclass Shot(pygame.sprite.Sprite):images = Nonecontainers = Nonelast_shot = 0shooting = Falsedef __init__(self, parent_, pos_, gl_, timing_=0, layer_=-1, surface_name_=''):"""Create a sprite shoot:param parent_: parent object class Player:param pos_: tuple (x:int, y:int); sprite shoot position (start position):param gl_: Constants (class GL):param timing_: integer; sprite refreshing time FPS, e.g 16ms is 60FPS:param layer_: integer; sprite layer (default 0 top layer):param surface_name_: string; surface name e.g 'BLUE_LASER'; surface = eval(BLUE_LASER')"""assert isinstance(parent_, Player1), \"Positional argument <parent_> is type %s , expecting class MirroredPlayer1Class instance." % type(parent_)assert isinstance(pos_, tuple), \"Positional argument <pos_> is type %s , expecting tuple." % type(pos_)assert isinstance(timing_, int), \"Positional argument <timing_> is type %s , expecting integer." % type(timing_)assert isinstance(layer_, int), \"Positional argument <layer_> is type %s , expecting integer." % type(layer_)assert isinstance(surface_name_, str), \"Positional argument <surface_name_> is type %s , " \"expecting python string." % type(surface_name_)if self.containers is None:raise ValueError('Shot.containers is not initialised.\nMake sure to assign the containers to'' a pygame group prior instantiation.\ne.g: Shot.containers = pygame.sprite.Group()')if self.images is None:raise ValueError("Shot.images is not initialised.\nMake sure to assign a texture to ""prior instantiation.\ne.g: Shot.images = 'P1_SURFACE'")if timing_ < 0:raise ValueError('Positional argument timing_ cannot be < 0')self.layer = layer_pygame.sprite.Sprite.__init__(self, self.containers)if isinstance(gl_.All, pygame.sprite.LayeredUpdates):if layer_:gl_.All.change_layer(self, layer_)self.images = Shot.imagesself.image = self.images[0] if isinstance(self.images, list) else self.imagesself.speed = pygame.math.Vector2(0, -35)self.timing = timing_self.pos = pos_self.gl = gl_self.position = pygame.math.Vector2(*self.pos)self.rect = self.image.get_rect(center=self.pos)self.dt = 0self.blend = pygame.BLEND_RGBA_ADD# todo test if convert_alpha otherwise this is uselessself.mask = pygame.mask.from_surface(self.image) # Image have to be convert_alpha compatibleself.index = 0self.parent = parent_self.surface_name = surface_name_self.id_ = id(self)if Shot.shooting and self.is_reloading(self.gl.FRAME):self.kill()else:self.gl.MIXER.stop_object(id(BLUE_LASER_SOUND))self.gl.MIXER.play(sound_=BLUE_LASER_SOUND, loop_=False, priority_=0, volume_=1.0,fade_out_ms=0, panning_=True, name_='BLUE_LASER_SOUND', x_=self.rect.centerx,object_id_=id(BLUE_LASER_SOUND), screenrect_=self.gl.SCREENRECT)self.sound_object = Broadcast(self.make_sound_object('BLUE_LASER_SOUND'))self.sound_object.play()Shot.last_shot = FRAMEShot.shooting = True# Create a network object self.shot_object = Broadcast(self.make_object())self.shot_object.queue()def make_sound_object(self, sound_name_: str) -> SoundAttr:"""Create a sound object for network broadcasting.:param sound_name_: string; representing the texture to use e.g 'BLUE_LASER_SOUND":return: Sound object, SoundAttr instance."""assert isinstance(sound_name_, str), \"Positional argument <sound_name_> is type %s , expecting python string." % type(sound_name_)if sound_name_ not in globals():raise NameError('Sound %s is not define.' % sound_name_)return SoundAttr(frame_=self.gl.FRAME, id_=self.id_, sound_name_=sound_name_, rect_=self.rect)def make_object(self) -> StaticSprite:"""Create a StaticSprite message object (see NetworkBroadcast library):return: StaticSprite object"""# Only attributes self.gl.FRAME change and self.rect are changing over the time.return StaticSprite(frame_=self.gl.FRAME, id_=self.id_, surface_=self.surface_name,layer_=self.layer, blend_=self.blend, rect_=self.rect)@staticmethoddef is_reloading(frame_: int) -> bool:"""Check if the player is shooting or reloading.Compare the actual FRAME number to the latest Shot frame number.Shot.last_shot default value is set to 0 during instantiation.Reloading time is hard encoded to 10 frames interval.When the player is ready to shoot, the shooting flag is set to false, otherwise stays True:frame_: integer; must be > 0 (Actual frame number):return: True or False. True player is reloading, False player is ready to shoot>>> Shot.shooting = True>>> Shot.last_shot = 0>>> Shot.is_reloading(9)True>>> assert Shot.shooting is True>>> Shot.is_reloading(10)False>>> Shot.is_reloading(-1)Traceback (most recent call last):...ValueError: frame_ must be >= 0"""assert isinstance(frame_, int), \"argument frame_ should be integer got %s" % type(frame_)if not frame_ >= 0:raise ValueError("frame_ must be >= 0")assert hasattr(Shot, 'last_shot'), 'Class Shot is missing attribute <last_shot>.'assert hasattr(Shot, 'shooting'), 'Class Shot is missing attribute <shooting>.'assert isinstance(Shot.last_shot, int), \"last_shot variable should be integer got %s" % type(Shot.last_shot)assert frame_ >= Shot.last_shot, \"Game constant frame_ value:%s should be > or equal to %s " % (frame_, Shot.last_shot)if frame_ - Shot.last_shot < 10:# still reloadingreturn Trueelse:# ready to shootShot.shooting = Falsereturn Falsedef collide(self, rect_: pygame.Rect, object_) -> None:"""Create a laser impact sprite:param rect_: pygqme.Rect object:param object_: object colliding with the rectangle:return: None"""assert isinstance(rect_, pygame.Rect), \'Positional argument rect_ should be a <pygame.Rect> type got %s ' % type(rect_)assert object_ is not None, 'Positional argument object_ cannot be None'# if sprite belongs to any group(s)if self.alive():LaserImpact.containers = self.gl.AllLaserImpact.images = IMPACT_LASERLaserImpact(gl_=self.gl, pos_=rect_.topleft, parent_=object_,timing_=self.timing, blend_=pygame.BLEND_RGBA_ADD, layer_=0)self.kill()def update(self) -> None:"""Update shot sprites whereabouts.sprite position is given by its rectangle.The position changed by incrementing the position with its speed vector (self.speed)if the sprite belongs to the screen dimensions, a message is broadcast to the client:return: None"""if self.dt > self.timing:if self.gl.SCREENRECT.colliderect(self.rect):# Move the laser spriteif self.images != IMPACT_LASER:self.position += self.speedself.rect.center = (self.position.x, self.position.y)self.dt = 0 else:self.kill()# broadcast network messageif self.rect.colliderect(self.gl.SCREENRECT):self.shot_object.update({'frame': self.gl.FRAME, 'rect': self.rect})self.shot_object.queue()self.dt += self.gl.TIME_PASSED_SECONDSclass Player1(pygame.sprite.Sprite):containers = Noneimage = Nonedef __init__(self, gl_, timing_=15, pos_: tuple = (0, 0), layer_=0):""":param gl_: Game constants (GL class) see GLOBAL library for more details:param timing_: integer; default 15ms (60 FPS):param pos_: tuple; (x:int, y:int) representing player 1 position (default x=0, y=0):param layer_: Sprite layer used by player 1"""assert isinstance(timing_, int), \"Positional argument <timing_> is type %s , expecting integer." % type(timing_)assert isinstance(pos_, tuple), \"Positional argument <pos_> is type %s , expecting tuple." % type(pos_)assert isinstance(layer_, int), \"Positional argument <layer_> is type %s , expecting integer." % type(layer_)if self.containers is None:raise ValueError('MirroredPlayer1Class.containers is not initialised.\nMake sure to assign the containers to'' a pygame group prior instantiation.\ne.g: MirroredPlayer1Class.containers = pygame.sprite.Group()')if self.image is None:raise ValueError("MirroredPlayer1Class.image is not initialised.\nMake sure to assign a texture to ""prior instantiation.\ne.g: MirroredPlayer1Class.image = 'P1_SURFACE'")pygame.sprite.Sprite.__init__(self, self.containers)assert isinstance(Player1.image, (pygame.Surface, list)), \"image is not a pygame.Surface or a list, got %s instead" % type(Player1.image)if timing_ < 0:raise ValueError('Positional argument timing_ cannot be < 0')self.image = Player1.imageself.image_copy = self.image.copy()self.rect = self.image.get_rect(center=pos_)self.timing = timing_self.surface_name = 'P1_SURFACE'self.gl = gl_self.dt = 0self.speed = 300self.layer = layer_self.blend = 0self.shooting = Falseself.previous_pos = pygame.math.Vector2() # previous positionself.life = 200 # player's lifeself.max_life = 200 # maximum lifeself.eng_right = self.right_engine() # instance for right engineself.eng_left = self.left_engine() # isntance for left engine# todo test if convert_alpha otherwise this is uselessself.mask = pygame.mask.from_surface(self.image) # Image have to be convert_alpha compatibleself.damage = 800 # -> gives 800 hit point of damage after collisionself.id_ = id(self)self.player_object = Broadcast(self.make_object())self.impact_sound_object = Broadcast(self.make_sound_object('IMPACT'))self.update_score = self.gl.P1_SCORE.score_updatedef make_sound_object(self, sound_name_: str) -> SoundAttr:"""Create a sound object for network broadcasting.:param sound_name_: string; representing the texture to use e.g 'BLUE_LASER_SOUND":return: Sound object, SoundAttr instance."""assert isinstance(sound_name_, str), \'Positional argument sound_name_ is not a string type, got %s ' % type(sound_name_)if sound_name_ not in globals():raise NameError('Sound %s is not define.' % sound_name_)return SoundAttr(frame_=self.gl.FRAME, id_=self.id_, sound_name_=sound_name_, rect_=self.rect)def make_object(self) -> StaticSprite:"""Create a sprite object for network broadcast similar to MirroredPlayer1Class:return: StaticSprite object (see NetworkBroadcast library for more details)"""# Only attributes self.gl.FRAME, self.rect are changing over the time.return StaticSprite(frame_=self.gl.FRAME, id_=self.id_, surface_=self.surface_name,layer_=self.layer, blend_=self.blend, rect_=self.rect, life=self.life, damage=self.damage)def player_lost(self):PlayerLost.containers = self.gl.AllPlayerLost.DIALOGBOX_READOUT_RED = DIALOGBOX_READOUT_REDPlayerLost.SKULL = SKULLfont = freetype.Font('/home/student/桌面/MultiplayerGameEngine-master/Assets/Fonts/Gtek Technology.ttf', size=14)PlayerLost(gl_=self.gl, font_=font, image_=FINAL_MISSION, layer_=0)def explode(self) -> None:"""Player explosion sprites and halo:return: None"""if self.alive():Explosion.images = EXPLOSION2Explosion(self, self.rect.center,self.gl, self.timing, self.layer, texture_name_='EXPLOSION2')PlayerHalo.images = HALO_SPRITE13PlayerHalo.containers = self.gl.AllPlayerHalo(texture_name_='HALO_SPRITE13', object_=self, timing_=10)self.player_lost()self.kill()def collide(self, damage_: int) -> None:"""MirroredPlayer1Class collide with object, transfer the damage and play the collision sound locallyif life < 1, trigger player1 explosion.:param damage_: integer; must be > 0 (total damage transferred to the player after collision.):return: None"""assert isinstance(damage_, int), \'Positional argument damage_ is not an int, got %s instead.' % type(damage_)assert damage_ > 0, 'damage_ argument should be > 0 'print(self.life, damage_, self.life - damage_)if self.alive():self.life -= damage_self.gl.MIXER.play(sound_=IMPACT, loop_=False, priority_=0,volume_=1.0, fade_out_ms=0, panning_=True,name_='IMPACT', x_=self.rect.centerx,object_id_=id(IMPACT),screenrect_=self.gl.SCREENRECT) self.impact_sound_object.play()"""def hit(self, damage_: int) -> None:#Transfer damage to the player after being hit.#:param damage_: integer > 0, damage transfer to the player#:return: Noneassert isinstance(damage_, int), \'Positional argument damage_ is not an int, got %s instead.' % type(damage_)assert damage_ > 0, 'damage_ argument should be > 0 'if self.alive():self.life -= damage_"""def left_engine(self) -> AfterBurner:"""Create a sprite for the left engine:return: AfterBurner instance"""if EXHAUST:AfterBurner.images = EXHAUSTelse:raise NameError('EXHAUST is not defined.')return AfterBurner(self, self.gl, (-22, 38),self.timing, pygame.BLEND_RGB_ADD, self.layer - 1, texture_name_='EXHAUST')def right_engine(self) -> AfterBurner:"""Create a sprite for the right engine:return: AfterBurner instance"""if EXHAUST:AfterBurner.images = EXHAUSTelse:raise NameError('EXHAUST is not defined.')return AfterBurner(self, self.gl, (22, 38),self.timing, pygame.BLEND_RGB_ADD, self.layer - 1, texture_name_='EXHAUST')def get_centre(self) -> tuple:"""Get MirroredPlayer1Class position.:return: tuple representing MirroredPlayer1Class rect centre"""return self.rect.centerdef disruption(self) -> None:"""Create an electric effect on MirroredPlayer1Class hull.:return: None"""if 'DISRUPTION' in globals():if isinstance(DISRUPTION, list):index = (FRAME >> 1) % len(DISRUPTION) - 1else:raise ValueError('DISRUPTION is not a list, got %s instead.' % type(DISRUPTION))else:raise NameError('DISRUPTION is not defined.')self.image.blit(DISRUPTION[index], (-20, -20), special_flags=pygame.BLEND_RGB_ADD)# self.disruption_object.update({'frame': self.gl.FRAME, 'surface': 'DISRUPTION',# 'rect': self.rect, 'index': index})# self.disruption_object.show(self.disruption_object)# self.disruption_object.queue()def shooting_effect(self) -> pygame.Surface:"""Apply a special effect on the aircraft hull when firing.:return: pygame.Surface"""if 'GRID' in globals():self.image.blit(GRID, (0, 0), special_flags=pygame.BLEND_RGB_ADD)else:raise NameError('GRID is not defined.')return self.imagedef update(self) -> None:"""Update MirroredPlayer1Class sprite:return: None"""self.rect.clamp_ip(self.gl.SCREENRECT)if self.dt > self.timing:self.image = self.image_copy.copy()if self.life < 1:self.explode()if self.gl.KEYS[pygame.K_UP]:self.rect.move_ip(0, -self.speed * self.gl.SPEED_FACTOR)if self.gl.KEYS[pygame.K_DOWN]:self.rect.move_ip(0, +self.speed * self.gl.SPEED_FACTOR)if self.gl.KEYS[pygame.K_LEFT]:self.rect.move_ip(-self.speed * self.gl.SPEED_FACTOR, 0)if self.gl.KEYS[pygame.K_RIGHT]:self.rect.move_ip(+self.speed * self.gl.SPEED_FACTOR, 0)# if self.gl.JOYSTICK is not None and self.gl.JOYSTICK.PRESENT:# x, y = self.gl.JOYSTICK.axes_status[0]if self.gl.KEYS[pygame.K_SPACE]:self.shooting_effect()Shot(self, self.rect.center, self.gl, 0, self.layer - 1, surface_name_='BLUE_LASER')if joystick is not None:self.rect.move_ip(JL3.x * self.gl.SPEED_FACTOR * self.speed,JL3.y * self.gl.SPEED_FACTOR * self.speed)if self.alive():# Broadcast the spaceship position every framesself.player_object.update({'frame': self.gl.FRAME,'rect': self.rect,'life': self.life})self.player_object.queue()if self.previous_pos == self.rect.center:self.rect.centerx += random.randint(-1, 1)self.rect.centery += random.randint(-1, 1)self.previous_pos = self.rect.center# !UPDATE the <follower> sprites with the new player position.self.eng_left.update()self.eng_right.update()else:self.dt += self.gl.TIME_PASSED_SECONDSself.disruption()class MirroredPlayer2Class(pygame.sprite.Sprite):def __init__(self, sprite_):"""Create an instance of Player2 on the server:param sprite_: object containing all attributes>>> import pygame>>> pygame.init()(8, 0)>>> SCREENRECT = pygame.Rect(0, 0, 800, 1024)>>> screen = pygame.display.set_mode(SCREENRECT.size, pygame.HWSURFACE, 32)>>> from Textures import P1_SURFACE, DISRUPTION>>> attributes = {'rect': pygame.Rect(0, 0, 0, 0),... 'image':eval('P1_SURFACE'), 'blend':0, 'layer':-1, 'id_':35555,... 'frame':0, 'damage': 800, 'life': 200, 'surface':'P1_SURFACE'}>>> sprite_ = pygame.sprite.Sprite()>>> for attr, value in attributes.items():... setattr(sprite_, attr, value)>>> spr = MirroredPlayer2Class(sprite_)>>> print(spr.surface)P1_SURFACE"""assert sprite_ is not None, 'Positional argument sprite_ is None.'attributes = ['rect', 'image', 'blend', 'layer', 'id_', 'frame', 'damage', 'life', 'surface']for attr in attributes:assert hasattr(sprite_, attr),\'Positional argument sprite_ is missing attribute %s ' % attrpygame.sprite.Sprite.__init__(self)self.rect = sprite_.rectself.image = sprite_.imageself.image_copy = sprite_.image.copy()self.blend = sprite_.blendself.layer = sprite_.layerself.id_ = sprite_.id_self.frame = sprite_.frameself.surface = sprite_.surfaceself.damage = sprite_.damageself.gl = GLdef disruption(self) -> None:if globals().__contains__('FRAME') and globals().__contains__('DISRUPTION'):index = (FRAME >> 1) % len(DISRUPTION) - 1self.image.blit(DISRUPTION[index], (-20, -20), special_flags=pygame.BLEND_RGB_ADD)def update(self) -> None:if self.image is None:raise ValueError('Cannot copy() NoneType.')self.image = self.image_copy.copy()self.disruption()class P2Shot(pygame.sprite.Sprite):def __init__(self, gl_, sprite_, timing_=0):""":param gl_: class GL (Constants):param sprite_: object containing all the original sprite attributes:param timing_: integer > 0 representing the refreshing time."""assert isinstance(gl_, type(GL)), \"Positional argument <gl_> is type %s , expecting class GL instance." % type(gl_)assert sprite_ is not None, 'Positional argument sprite_ is None.'attributes = ['rect', 'image', 'blend', 'layer', 'id_', 'surface']for attr in attributes:assert hasattr(sprite_, attr), \'Positional argument sprite_ is missing attribute %s ' % attrif timing_ < 0:raise ValueError('argument timing_ must be > 0')pygame.sprite.Sprite.__init__(self)self.rect = sprite_.rectself.image = sprite_.imageself.blend = sprite_.blendself.layer = sprite_.layerself.id_ = sprite_.id_self.surface = sprite_.surfaceself.gl = gl_self.timing = timing_def collide(self, rect_, object_) -> None:""":param rect_: pygame.Rect type:param object_::return:"""if hasattr(GL, 'All'):LaserImpact.containers = GL.Allelse:raise AttributeError('Class GL missing attribute All.')if IMPACT_LASER:LaserImpact.images = IMPACT_LASERelse:raise NameError('IMPACT_LASER is not define.')LaserImpact(gl_=self.gl, pos_=rect_.topleft, parent_=object_,timing_=self.timing, blend_=pygame.BLEND_RGBA_ADD, layer_=0)def update(self) -> None:...class SpriteServer(threading.Thread):def __init__(self,gl_, # Global variables classhost_: str, # host address (string)port_: int, # port value (integer)):""":param gl_: class GL:param host_: string; ip address:param port_: integer; port to use"""assert isinstance(host_, str), \"Positional argument <host_> is type %s , expecting string." % type(host_)assert isinstance(port_, int), \"Positional argument <port_> is type %s , expecting integer" % type(port_)threading.Thread.__init__(self)self.gl = gl_self.gl.SPRITE_SERVER_STOP = Falsetry:self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)except socket.error as error:print('\n[-]SpriteServer - ERROR : %s %s' % (error, time.ctime()))gl_.P1CS_STOP = Trueself.gl.SPRITE_SERVER_STOP = Truetry:self.sock.bind((host_, port_))self.sock.listen(1)except socket.error as error:print('\n[-]SpriteServer - ERROR : %s %s' % (error, time.ctime()))gl_.P1CS_STOP = Trueself.gl.SPRITE_SERVER_STOP = Trueself.buf = self.gl.BUFFERself.total_bytes = 0self.view = memoryview(bytearray(self.buf))def run(self):# Accept a connection. The socket must be bound to# an address and listening for connections.# The return value is a pair (conn, address) where# conn is a new socket object usable to send and receive# data on the connection, and address is the address# bound to the socket on the other end of the connection.connection = Nonetry:# The thread will be stopped here until first connectionconnection, client_address = self.sock.accept()except socket.error as error:print("\n[-]SpriteServer - Lost connection with Player 2 ...")print("\n[-]SpriteServer - ERROR %s %s" % (error, time.ctime()))self.gl.P1CS_STOP = Truewhile not self.gl.P1CS_STOP and not self.gl.SPRITE_SERVER_STOP:# try:while not self.gl.P1CS_STOP and not self.gl.SPRITE_SERVER_STOP:# Receive data from the socket, writing it into buffer instead# of creating a new string. The return value is a pair (nbytes, address)# where nbytes is the number of bytes received and address is the address# of the socket sending the data.try:nbytes, sender = connection.recvfrom_into(self.view, self.buf)except socket.error as error:print("\n[-]SpriteServer - Lost connection with Player 2 ...")print("\n[-]SpriteServer - ERROR %s %s" % (error, time.ctime()))# signal to kill both threads SpriteServer and SpriteClient# todo : Player 2 is now deconnected from the server and should not be# display on the server display, create a method to kill the sprite of Player 2self.gl.SPRITE_SERVER_STOP = Truenbytes = 0buffer = self.view.tobytes()[:nbytes]try:connection.sendall(self.view.tobytes()[:nbytes])except ConnectionResetError as error:print("\n[-]SpriteServer - Lost connection with Player 2 ...")print("\n[-]SpriteServer - ERROR %s %s" % (error, time.ctime()))# todo : Player 2 is now deconnected from the server and should not be# display on the server display, create a method to kill the sprite of Player 2# signal to kill both threads SpriteServer and SpriteClientself.gl.SPRITE_SERVER_STOP = Truetry:# Decompress the data framedecompress_data = lz4.frame.decompress(buffer)data = cpickle.loads(decompress_data)except Exception:# The decompression error can also happen when# the bytes stream sent is larger than the buffer size.# todo : Player 2 is now deconnected from the server and should not be# display on the server display, create a method to kill the sprite of Player 2# signal to kill both threads SpriteServer and SpriteClientself.gl.SPRITE_SERVER_STOP = Trueself.gl.SPRITE_CLIENT_STOP = Truedata = None# todo check if self.gl.NetGroupAll.empty() is faster# self.gl.NetGroupAll = LayeredUpdatesModified()data_set = set()if isinstance(data, list):for sprite_ in data:# print(GL.FRAME, sprite_.id_, sprite_.surface if hasattr(sprite_, "surface") else None)if hasattr(sprite_, 'event'):continueelif hasattr(sprite_, 'sound_name'):try:sound = eval(sprite_.sound_name)except NameError:raise NameError("\n[-]SpriteServer - Sound effect ""'%s' does not exist " % sprite_.sound_name)# self.gl.MIXER.stop_object(id(sound))# play the sound locallyself.gl.MIXER.play(sound_=sound, loop_=False, priority_=0,volume_=1.0, fade_out_ms=0, panning_=True,name_=sprite_.sound_name, x_=sprite_.rect.centerx,object_id_=id(sound),screenrect_=self.gl.SCREENRECT)# data.remove(sprite_)else:assert hasattr(sprite_, 'surface'), "\nBroadcast message is missing <surface> attribute."try:sprite_.image = eval(sprite_.surface) # load surfaceexcept (NameError, AttributeError):raise RuntimeError("\n[-]SpriteServer - Surface ""'%s' does not exist " % sprite_.surface)if isinstance(sprite_.image, list):sprite_.image = sprite_.image[sprite_.index % len(sprite_.image) - 1]# --- Apply transformation ---# Apply transformation to texture rotation/scale and# store the transformation inside a buffer# Check if the texture has been already transformed and use# the buffer transformation instead (for best performance).if hasattr(sprite_, 'rotation'):if sprite_.rotation is not None and sprite_.rotation != 0:if sprite_.id_ in self.gl.XTRANS_ROTATION.keys():sprite_.image = self.gl.XTRANS_ROTATION[sprite_.id_]else:sprite_.image = pygame.transform.rotate(sprite_.image, sprite_.rotation)self.gl.XTRANS_ROTATION.update({sprite_.id_: sprite_.image})if hasattr(sprite_, 'scale'):if sprite_.scale != 1:if sprite_.id_ in self.gl.XTRANS_SCALE.keys():sprite_.image = self.gl.XTRANS_SCALE[sprite_.id_]else:sprite_.image = pygame.transform.scale(sprite_.image, (int(sprite_.image.get_size()[0] * sprite_.scale),int(sprite_.image.get_size()[1] * sprite_.scale)))self.gl.XTRANS_SCALE.update({sprite_.id_: sprite_.image})s = None# find Player 2if sprite_.surface == 'P2_SURFACE':s = MirroredPlayer2Class(sprite_)# find player 2 shotselif sprite_.surface == "RED_LASER":s = P2Shot(self.gl, sprite_, 16)# generic sprite that doesn't have# to be instantiated with specific methodselse:# Generic sprite (without methods)s = pygame.sprite.Sprite()s.frame = sprite_.frames.rect = sprite_.rects.surface = sprite_.surfaces.image = sprite_.images.blend = sprite_.blends.layer = sprite_.layers.id_ = sprite_.id_if hasattr(sprite_, 'life'):s.life = sprite_.lifeif hasattr(sprite_, 'damage'):s.damage = sprite_.damage# Add broadcast sprites to DATA_SET (reset every time a message from client is received).# DATA_SET contains all sprites sent by the client for a specific frame number.# The DATA_SET cannot contains duplicates. The id attribute (memory location)# is used as unique identification number to store sprites in the DATA_SET.# The element in data set represent all active (alive) sprites display on the# client side (before client collision detection).data_set.add(sprite_.id_)# Add the sprite in self.gl.NetGroupAll (if not already in the group) or# update position and texture.# NetGroupAll, will be used in the main loop (locally) to display# all the sprites broadcast from a specific frame number.# If a sprite is not added to that group, it will be ignored# and not display on the client side.if s is not None and len(self.gl.NetGroupAll) > 0:has_ = Falsefor sprites in self.gl.NetGroupAll:if sprites.id_ == s.id_:has_ = Truesprites.rect = s.rectsprites.image = sprite_.imagesprites.frame = sprite_.framebreakif not has_:self.gl.NetGroupAll.add(s)else:self.gl.NetGroupAll.add(s)# Compare NetGroupAll group to DATA_SET and delete sprite(s)# accordingly. Sprites in NetGroupAll and not in DATA_SET will# be killed and remove from every groups they are belonging to.# When a sprite is deleted, the transformation/scale buffer associated# to it will be deleted (using its id).for spr_ in self.gl.NetGroupAll:if spr_.id_ not in data_set:spr_.kill()if spr_.id_ in self.gl.XTRANS_SCALE.keys():self.gl.XTRANS_SCALE.pop(spr_.id_)if spr_.id_ in self.gl.XTRANS_ROTATION.keys():self.gl.XTRANS_ROTATION.pop(spr_.id_)# Reload original texture# for pair in modified_surface.items():# globals()[pair[0]] = pair[1]buffer = b''# data fully received breaking the loop, clear the bufferbreak# pygame.time.wait(1)"""except Exception as error:print('\n[-]SpriteServer - ERROR @ frame: %s : %s %s' % (FRAME, error, time.ctime()))finally:# Clean up the connectionif 'connection' in globals() and connection is not None:connection.close()"""print('\n[-]SpriteServer is now terminated...')def force_quit(host_: str, port_: int) -> None:"""function used for terminating SERVER/ CLIENT threads listening (blocking socket):param host_: string; ip address:param port_: integer; port to use:return: None"""assert isinstance(host_, str), \"Positional argument <host_> is type %s , expecting string." % type(host_)assert isinstance(port_, int), \"Positional argument <port_> is type %s , expecting integer." % type(port_)# todo create assert ( port should be > 1024)sock = Nonetry:sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.connect((host_, port_))data = cpickle.dumps(b"QUIT")sock.sendall(data)print("\n[+]Termination signal sent to SpriteServer...")except Exception as error:print("\n[-]Cannot send termination signal to SpriteServer...")print("\n[-]ERROR %s " % error)finally:if 'sock' in globals() and isinstance(sock, socket.socket):sock.close()def collision_detection():p2_shots = pygame.sprite.Group()p2 = Nonefor sprite_ in GL.NetGroupAll:# detect player spriteif hasattr(sprite_, 'surface'):if sprite_.surface == "P2_SURFACE":p2 = sprite_continue# detect player 2 shots and add them to a specific# group p2_shots. p2_shots has to be destroyed before# leaving the function.elif sprite_.surface == "RED_LASER":p2_shots.add(sprite_)if P1 is not None and P1.alive():# Player 1 collision with asteroid# Use collision mask for collision detection# It is compulsory to have sprite textures with alpha transparency information# in order to check for collision otherwise the collision will be ignored.collision = pygame.sprite.spritecollideany(P1, GL.ASTEROID, collided=pygame.sprite.collide_mask)if collision is not None:P1.collide(collision.damage)if hasattr(collision, 'collide'):collision.collide(P1, P1.damage)else:print(type(collision))raise AttributeError# Player 1 shots collision with asteroids# same than abovefor shots, asteroids in pygame.sprite.groupcollide(GL.PLAYER_SHOTS, GL.ASTEROID, 0, 0, collided=pygame.sprite.collide_mask).items():if asteroids is not None:for aster in asteroids:if hasattr(aster, 'hit'):aster.hit(P1, 100)new_rect = shots.rect.clamp(aster.rect) # todo need to make sure shots is not a listshots.collide(rect_=new_rect, object_=aster)else:print(type(aster))raise AttributeError# Player 2 shots colliding with asteroidif p2 is not None and p2.alive():for shots, asteroids in pygame.sprite.groupcollide(p2_shots, GL.ASTEROID, 0, 0).items(): # ,collided=pygame.sprite.collide_mask).items():if asteroids is not None:for aster in asteroids:if hasattr(aster, 'hit'):aster.hit(None, 100)new_rect = shots.rect.clamp(aster.rect) # todo need to make sure shots is not a listshots.collide(rect_=new_rect, object_=aster)else:print(type(aster))raise AttributeErrorfor spr in GL.NetGroupAll:if spr.id_ == shots.id_:spr.kill()# Use collision mask for collision detection# Check collision between Player 2 and asteroidsif p2 is not None and p2.alive():collision = pygame.sprite.spritecollideany(p2, GL.ASTEROID, collided=pygame.sprite.collide_mask)if collision is not None:# Cannot send damage to player 2, this# is done on the remote host in the collision detection section# Pass only damage to the asteroidcollision.collide(p2.damage)# MirroredTransportClass collision with asteroidif T1 is not None and T1.alive():# todo check collision maskscollision = pygame.sprite.spritecollideany(T1, GL.ASTEROID, collided=pygame.sprite.collide_mask)if collision is not None:T1.collide(collision.damage)if hasattr(collision, 'collide'):collision.collide(T1, T1.damage)else:print(type(collision))raise AttributeErrorp2_shots.remove()p2_shots.empty()del p2_shotsdef window():scrw_half = SCREENRECT.w >> 1scrh_half = SCREENRECT.h >> 1w, h = FRAMEBORDER.get_size()screen.blit(BACKGROUND, (0, 0))screen.blit(FRAMEBORDER, (scrw_half - (w >> 1), scrh_half - (h >> 1)))font = freetype.Font(os.path.join('Assets/Fonts/', 'ARCADE_R.TTF'), size=15)frame_ = FRAME.copy()rect = font.get_rect("Waiting for connection...")font.render_to(frame_, ((frame_.get_width() - rect.w) // 2,(frame_.get_height() - rect.h) // 2),"Waiting for connection...",fgcolor=pygame.Color(255, 255, 255), size=15)screen.blit(frame_, (scrw_half - (w >> 1) + 20, scrh_half - (h >> 1) + 40))clock = pygame.time.Clock()frame = 0while GL.CONNECTION is False:screen.blit(BACKGROUND, (0, 0))pygame.event.pump()Square()GL.All.update()GL.All.draw(screen)screen.blit(frame_, (scrw_half - (w >> 1) + 20, scrh_half - (h >> 1) + 40))GL.TIME_PASSED_SECONDS = clock.tick(70)frame += 1pygame.display.flip()"""frame = 0frame_ = FRAME.copy()for s, t in GL.CLIENTS.items():font.render_to(frame_, ((frame_.get_width() - rect.w) // 2,(frame_.get_height() - rect.h) // 2),'Client connected : ' + str(s) + ':' + str(t),fgcolor=pygame.Color(255, 255, 255), size=15)while 1:pygame.event.pump()screen.blit(BACKGROUND, (0, 0))screen.blit(frame_, (scrw_half - (w >> 1) + 20, scrh_half - (h >> 1) + 40))GL.TIME_PASSED_SECONDS = clock.tick(70)frame += 1pygame.display.flip()..."""class Square(pygame.sprite.Sprite):def __init__(self):self.layer = -1pygame.sprite.Sprite.__init__(self, GL.All)if isinstance(GL.All, pygame.sprite.LayeredUpdates):if self.layer:GL.All.change_layer(self, self.layer)self.image = pygame.Surface((randint(200, 500), randint(200, 500)))self.image.fill((10, 15, 25, 15))self.image.convert(32, pygame.RLEACCEL)self.rect = self.image.get_rect(center=(randint(0, SCREENRECT.w),randint(0, SCREENRECT.h)))self.dt = 0self.blend = pygame.BLEND_RGBA_ADDself.i = 128def update(self):self.image.set_alpha(self.i)self.i -= 10if self.i < 0:self.kill()if __name__ == '__main__':RECT = pygame.sprite.Group()import doctestdoctest.testmod()SERVER = '127.0.0.1'CLIENT = '127.0.0.1'# SERVER = '192.168.0.1'# CLIENT = '192.168.0.4'SCREENRECT = pygame.Rect(0, 0, 800, 1024)GL.SCREENRECT = SCREENRECTscreen = pygame.display.set_mode(SCREENRECT.size, pygame.HWSURFACE, 32)GL.SCREEN = screenpygame.display.set_caption('PLAYER 1')# *********************************************************************# JOYSTICK joystick_count = pygame.joystick.get_count()if joystick_count > 0:joystick = pygame.joystick.Joystick(0)joystick.init()else:joystick = NoneGL.JOYSTICK = joystickfrom Textures import *from Sounds import BLUE_LASER_SOUND, RED_LASER_SOUND, EXPLOSION_SOUND, IMPACT, IMPACT1from Backgrounds import Backgroundfrom Asteroids import Asteroidfrom MessageSender import SpriteClientfrom Transports import Transport# background vectorvector1 = pygame.math.Vector2(x=0, y=0)vector2 = pygame.math.Vector2(x=0, y=-1024)# ********************************************************************# NETWORK SERVER / CLIENT# SpriteServer -> receive client(s) positions# 1) Start the Server to receive client(s) position(s)# If no connection is made, the thread will remains listening/running# in the background, except if an error is raised.server = SpriteServer(GL, SERVER, 1025)server.start()# SpriteClient -> forward all sprites positions# 2) Start the Client to send all sprites positions to client(s)client = SpriteClient(gl_=GL, host_=CLIENT, port_=1024)client.start()# Killing threads if no client connectedif not client.is_alive() or GL.CONNECTION is False:print('No player detected')GL.SPRITE_CLIENT_STOP = TrueGL.SPRITE_SERVER_STOP = Trueforce_quit(SERVER, 1025)window()# *********************************************************************GL.All = LayeredUpdatesModified()GL.ASTEROID = pygame.sprite.Group()GL.PLAYER_SHOTS = pygame.sprite.Group()GL.TRANSPORT = pygame.sprite.GroupSingle()Player1.image = P1_SURFACEPlayer1.containers = GL.AllShot.images = BLUE_LASERShot.containers = GL.All, GL.PLAYER_SHOTSExplosion.containers = GL.AllBackground.containers = GL.AllAfterBurner.containers = GL.AllAsteroid.containers = GL.All, GL.ASTEROIDAsteroid.image = DEIMOSTransport.image = TRANSPORTTransport.containers = GL.All, GL.TRANSPORTBackground.image = BACK1_SBackground(vector_=pygame.math.Vector2(0, 1), position_=vector2, gl_=GL, layer_=-2, event_name_='BACK1_S')Background.image = BACK2_SBackground(vector_=pygame.math.Vector2(0, 1), position_=vector1, gl_=GL, layer_=-2, event_name_='BACK2_S')Background.image = CL1Background(vector_=pygame.math.Vector2(0, 2.5),position_=pygame.math.Vector2(x=0, y=-480),gl_=GL, layer_=-2, blend_=pygame.BLEND_RGB_ADD, event_name_='CL1')Background.image = CL2Background(vector_=pygame.math.Vector2(0, 2.5),position_=pygame.math.Vector2(x=randint(0, 800), y=200),gl_=GL, layer_=-2, blend_=pygame.BLEND_RGB_ADD, event_name_='CL2')ShootingStar.containers = GL.AllShootingStar.image = SHOOTING_STARDisplayScore.containers = GL.AllDisplayScore.images = pygame.Surface((10, 10))GL.P1_SCORE = DisplayScore(gl_=GL, timing_=15)MakeGems.containers = GL.AllP1 = Player1(GL, 15, (screen.get_size()[0] // 2, screen.get_size()[1] // 2))# P1 = NoneT1 = Transport(gl_=GL, timing_=15,pos_=(SCREENRECT.w >> 1,(SCREENRECT.h >> 1) - 100), surface_name_='TRANSPORT', layer_=0)life_bar = HorizontalBar(start_color=pygame.Color(0, 7, 255, 0),end_color=pygame.Color(120, 255, 255, 0),max_=P1.max_life, min_=0,value_=P1.life,start_color_vector=(0, 1, 0), end_color_vector=(0, 0, 0), alpha=False, height=32, xx=200,scan=True)transport_life_bar = HorizontalBar(start_color=pygame.Color(255, 7, 15, 0),end_color=pygame.Color(12, 12, 255, 0),max_=T1.max_life, min_=0,value_=T1.life,start_color_vector=(0, 1, 0), end_color_vector=(0, 0, 0), alpha=False, height=32,xx=200,scan=True)GL.TIME_PASSED_SECONDS = 0clock = pygame.time.Clock()GL.STOP_GAME = FalseFRAME = 0GL.FRAME = 0GL.MIXER = SoundControl(30)f = open('P1_log.txt', 'w')while not GL.STOP_GAME:pygame.event.pump()# print('Server frame # %s vector1 %s vector2 %s' % (FRAME, vector1, vector2))# Send an event to the client triggering the next frameGL.NEXT_FRAME.set() # set the eventevent_obj = EventAttr(event_=GL.NEXT_FRAME, frame_=GL.FRAME)Broadcast(event_obj).next_frame()# Create cosmic dustif GL.FRAME % 10 == 0:if len(COSMIC_DUST_ARRAY) < 15:create_dust(GL)if len(GL.ASTEROID) < 15:asteroid = random.choices(['DEIMOS', 'EPIMET'])[0]scale = random.uniform(0.1, 0.5)rotation = random.randint(0, 360)Asteroid.image = pygame.transform.rotozoom(eval(asteroid).copy(), rotation, scale)GL.ASTEROID.add(Asteroid(asteroid_name_=asteroid,gl_=GL, blend_=0, rotation_=rotation,scale_=scale, timing_=16, layer_=-2))if joystick is not None:JL3 = pygame.math.Vector2(joystick.get_axis(0), joystick.get_axis(1))for event in pygame.event.get():keys = pygame.key.get_pressed()GL.KEYS = keysif event.type == pygame.QUIT:print('Quitting')GL.STOP_GAME = Trueif keys[pygame.K_ESCAPE]:GL.STOP_GAME = Trueif keys[pygame.K_F8]:pygame.image.save(screen, 'dump0.png')if event.type == pygame.MOUSEMOTION:GL.MOUSE_POS = pygame.math.Vector2(event.pos)if random.randint(0, 1000) > 985:shoot = ShootingStar(gl_=GL, layer_=0, timing_=16, surface_name_='SHOOTING_STAR')# update sprites positions and add sprites transformation# At this stage no sprites are display onto the screen. Therefore,# sprite's methods blit directly surface or image onto the screen# will takes the risk to see their surfaces overlay by another sprites surface while calling# any group's draw methods (see below)GL.All.update()# Authorize Player 1 to send data to the client.# Allowing to send only one set of data every frame.# The clear method is used in the class SpriteClient# right after receiving the EventGL.SIGNAL.set()# Always display the group GL.All first has it contains the background surfaces# Any sprite attached to the group GL.All and blit directly to the screen surface# will be override by the network sprite if sprites occupy the same location..# Ideally all sprites should be on the same group in order to draw them ordered by# their layer number.# Todo :# create single group type pygame.sprite.layerUpdatesModified() group by adding network sprites directly# into the GL.All group (also pygame.sprite.layerUpdatesModified())# Note, all network sprites added to the GL.All group have to be killed after being blit onto# the display to avoid filling up the group of new instances (Broadcast class calls will add a# new sprite instances to the group GL.All each frames without killing the previous one, with the# effect of slowing down the game loop and displaying un-necessary sprites.GL.All.draw(screen)# Draw the network sprite above the backgroundif GL.CONNECTION:GL.NetGroupAll.update() # -> run all the update methodGL.NetGroupAll.draw(screen)# *************************************************************# Draw here all the other sprites that does not belongs to# common groups (GL.All & GL.NetGroupAll).# Sprite blit last onto the display are at the top layer.# Be aware that any surface(s) blit with blend attribute will# also blend with the entire sprite scene (blending with# sprites from all layers)# e.g Drawing GUI and life/energy sprite bars, screen bullet impacts# special effects, final score, ending screen and text inputs etc.# Update the sound ControllerGL.MIXER.update()collision_detection()GL.TIME_PASSED_SECONDS = clock.tick(70)GL.SPEED_FACTOR = GL.TIME_PASSED_SECONDS / 1000GL.FPS.append(clock.get_fps())# half = SCREENRECT.w >> 1# safe_zone = pygame.Rect(half - 200, half, 400, SCREENRECT.bottom - half)# pygame.draw.rect(screen, pygame.Color(255, 0, 0, 0), safe_zone, 1)# dust particles (show on the top of all other sprites)if len(COSMIC_DUST_ARRAY) > 0:display_dust(GL)if P1.life > 1:life_bar.VALUE = int(P1.life)life = life_bar.display_gradient()screen.blit(life, (10, 10), special_flags=0)screen.blit(life_bar.display_value(), (50, 10))if T1.life > 1:transport_life_bar.VALUE = int(T1.life)life = transport_life_bar.display_gradient()screen.blit(life, (SCREENRECT.w // 2 + 100, 10), special_flags=0)screen.blit(transport_life_bar.display_value(), (SCREENRECT.w // 2 + 150, 10))pygame.display.flip()FRAME += 1GL.FRAME = FRAMEBroadcast.empty()# for r in GL.All:# print(r)"""print(GL.FRAME)for r in GL.NetGroupAll:f.write('\n NETGROUPALL ' + str(GL.FRAME) + " ")f.write(' Surface: ' + str(r.surface) if hasattr(r, 'surface') else str(r))f.write(' Rect: ' + str(r.rect) if hasattr(r, 'rect') else '')f.write(' id: ' + str(r.id_))for r in GL.All:f.write('\n GL.All ' + str(GL.FRAME) + ' ')f.write(' Surface: ' + str(r.surface) if hasattr(r, 'surface') else str(r))f.write(' Rect: ' + str(r.rect) if hasattr(r, 'rect') else '')f.write(' id: ' + str(r.id_) if hasattr(r, 'id_') else '')"""f.close()GL.SPRITE_CLIENT_STOP = TrueGL.SPRITE_SERVER_STOP = Trueforce_quit(SERVER, 1025)import matplotlib.pyplot as pltplt.title("FPS ")# plt.plot(GL.BYTES_SENT)plt.plot(GL.FPS)plt.draw()plt.show()plt.title("BYTES RECEIVED")plt.plot(GL.BYTES_RECEIVED)plt.draw()plt.show()pygame.quit()

運行效果如下圖:


游戲中的玩家1和玩家2


GameOver!


player1服務端+玩家1
player2玩家2(玩家2在大母艦的下面!)

看了是不是很激動呢!由于代碼量過多,后續我回逐個發出(點擊關注+點贊不迷路哦!)

總結

以上是生活随笔為你收集整理的Python3.7版---双人联机雷霆战机(2D特效+音效+道具+Linux系统)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

久久精品这里热有精品 | 日日天天狠狠 | 国产高清成人 | 国产一级特黄毛片在线毛片 | 黄色免费观看网址 | 亚洲成人精品 | 97精品国产97久久久久久粉红 | 日韩91av| 欧美 高跟鞋交 xxxxhd | 国产极品尤物在线 | 国产精品午夜久久久久久99热 | 黄色的网站免费看 | 97精品国产97久久久久久 | 亚洲精品xx | 亚洲国产网站 | 国产最新在线观看 | 欧美激情精品 | 特级黄色视频毛片 | 中文字幕888 | 日韩网站在线看片你懂的 | 麻豆精品国产传媒 | 成年人免费在线观看网站 | 国产一区二区播放 | 日韩 精品 一区 国产 麻豆 | 欧美日韩精品在线 | 波多野结衣电影一区二区三区 | 久久乱码卡一卡2卡三卡四 五月婷婷久 | 一区二区高清在线 | 91在线入口| 91网在线| 97品白浆高清久久久久久 | 在线视频日韩欧美 | 免费网站在线观看成人 | 狠狠操导航 | 一区二区三区在线免费 | 久久久久久久国产精品 | 国产高清视频免费观看 | www.人人草 | 国产精品久久人 | 欧美精品免费在线观看 | 视色网站| 久久99热这里只有精品国产 | 日本在线观看一区二区三区 | 国产99在线免费 | 国产一区二区久久精品 | 超碰国产人人 | 91看片黄色| 99久久婷婷国产综合精品 | 麻豆超碰 | 精品国偷自产国产一区 | 麻豆视频在线播放 | 国产免费一区二区三区网站免费 | 国产成人一区三区 | 欧美91av| 91丨九色丨蝌蚪丨老版 | 日韩在线看片 | 成人v| 91亚洲精 | 色婷婷久久久 | 在线观看午夜 | 亚洲精品乱码久久久久久按摩 | 在线黄频| 久久99热这里只有精品国产 | 久草视频在线免费播放 | 国产视频精品久久 | 中文字幕一区二区三区乱码在线 | 国产99爱| 亚洲精品中文字幕在线观看 | 日韩在线观看的 | 久久av观看 | 91成人网在线观看 | 日本黄色片一区二区 | 国产成人99av超碰超爽 | 日韩免费电影一区二区 | 中文字幕在线观看免费 | 欧美国产日韩久久 | 成人一级片免费看 | 天天曰| 97综合网| 看黄色91 | 一区视频在线 | 国产精品视频免费观看 | 久久久私人影院 | 一区二区三区四区精品视频 | 久草在线视频首页 | 久久精品婷婷 | 国语黄色片| 日日夜夜骑| 在线韩国电影免费观影完整版 | 一区二区激情视频 | 国产精品毛片一区二区三区 | 日韩一区二区免费播放 | 国产日韩精品一区二区三区在线 | 人人澡人人爽欧一区 | 久久6精品 | 欧美另类美少妇69xxxx | 亚洲综合激情小说 | av在线网站大全 | 高清av不卡 | 国产精品美女久久久久久免费 | 国产精品视频免费在线观看 | 激情五月婷婷综合网 | 亚洲午夜久久久久久久久久久 | 一本一本久久a久久精品综合小说 | 最近日本mv字幕免费观看 | 久久香蕉国产精品麻豆粉嫩av | 日韩在线观看中文 | 国语麻豆| 久久久精品 一区二区三区 国产99视频在线观看 | 美女黄频在线观看 | 国产精品video爽爽爽爽 | 天天操天天拍 | 在线免费看黄色 | 国产午夜三级一区二区三桃花影视 | 国产手机视频在线 | 激情视频在线观看网址 | 五月婷婷丁香网 | 日韩一区精品 | 中文字幕一区二区三区久久 | 亚洲成人av免费 | 精油按摩av | 亚洲www天堂com| 色网站在线免费观看 | www.久热 | 日韩久久在线 | 天天干天天干 | 偷拍视频一区 | 成人黄色小说视频 | 中文字幕一区在线观看视频 | 国产成人一区二区在线观看 | 天天爱天天色 | 久久人人爽人人爽人人片av免费 | 一区二区三区日韩在线 | 99视频在线免费播放 | 精品一区在线看 | 夜夜操网站 | 99久久婷婷国产一区二区三区 | 激情电影在线观看 | 欧美最猛性xxxxx亚洲精品 | 国产精品久久久久久久久久三级 | 成人免费在线观看av | 久久国产精品免费一区 | 久久99国产精品二区护士 | 国产综合在线视频 | 96视频免费在线观看 | 精品91久久久久 | 国产偷v国产偷∨精品视频 在线草 | 超碰夜夜 | 国产精品久久久精品 | 久久伊人综合 | av在线网站观看 | 国产91精品一区二区绿帽 | 久久蜜桃av | 亚洲色图22p| 国产一线二线三线在线观看 | 黄色午夜 | 99在线精品免费视频九九视 | 99r精品视频在线观看 | 成人av在线直播 | 欧美另类xxx | 米奇狠狠狠888 | 最近更新的中文字幕 | 日韩欧美第二页 | 国产一区免费在线观看 | 黄色成人av网址 | 热re99久久精品国产99热 | 久久这里只有精品1 | 国产福利精品一区二区 | www.伊人网.com| 国产女人免费看a级丨片 | 国产精品久久久久一区二区 | 玖玖爱国产在线 | 欧美日韩一区三区 | 啪啪精品| 香蕉视频啪啪 | 欧美一级特黄aaaaaa大片在线观看 | 中文字幕一区二区在线观看 | 久影院| 亚洲资源在线网 | 国产日韩精品欧美 | av电影不卡在线 | 在线播放国产精品 | 国产精品久久影院 | 日韩1级片 | 日本黄色免费电影网站 | 99热99re6国产在线播放 | 最新中文字幕 | 欧美人人 | 国产三级香港三韩国三级 | 精品国产久 | 免费精品人在线二线三线 | 黄色av一级片 | 国产麻豆精品在线观看 | 五月天久久婷婷 | av综合在线观看 | 一级片免费观看视频 | 四虎免费在线观看 | 国产成人精品久久久久 | 国产亚洲精品久久久久久无几年桃 | 黄色免费观看视频 | 2018好看的中文在线观看 | 天天干,夜夜操 | 日韩在线一级 | 国产精品成人a免费观看 | 久久露脸国产精品 | 天天射天天射 | 国产精品美女久久久免费 | 日韩精品久久久 | 久久99视频免费观看 | 中文字幕资源网 国产 | 免费看毛片网站 | 麻豆一区二区 | 亚洲国产精品免费 | 成片人卡1卡2卡3手机免费看 | 久热免费在线观看 | 免费网站污 | 久久av免费| 日韩欧美一区二区三区在线 | 久久久久久电影 | 日韩伦理片hd | 日韩在线视频网站 | 久久综合国产伦精品免费 | 久久 一区 | 超碰免费观看 | 午夜av免费在线观看 | 亚洲精区二区三区四区麻豆 | 国产精品久久精品国产 | 麻豆视频一区 | 久久久久国产精品免费网站 | 欧美福利久久 | 韩日三级在线 | 99热这里 | 激情av资源网 | 激情综合五月 | 亚洲精品资源 | 精品在线亚洲视频 | 久久久久久久电影 | 丁香资源影视免费观看 | 99爱在线观看 | 91超碰在线播放 | 97日日碰人人模人人澡分享吧 | 成人一级片免费看 | 免费观看黄 | 最近免费中文字幕 | 在线午夜av | 肉色欧美久久久久久久免费看 | 国内精品久久久精品电影院 | 欧美精品一二 | 亚洲精品免费在线观看视频 | 国产色啪 | 91传媒视频在线观看 | 四虎在线视频免费观看 | 日韩欧美高清在线观看 | 欧美日本不卡视频 | www五月婷婷 | 国产专区第一页 | 欧美性爽爽 | 天堂麻豆 | 国产又粗又猛又黄又爽视频 | 伊人狠狠色丁香婷婷综合 | 日本性动态图 | 亚洲精品免费看 | 亚洲在线a| 日韩四虎| 国产精品一区二 | 欧美精品在线一区 | 久草在线视频看看 | 色综合久久中文综合久久牛 | 欧美日韩国产成人 | 国产精品入口66mio女同 | 西西444www大胆高清图片 | 在线 欧美 日韩 | 综合影视 | 97成人在线观看视频 | 中文字幕av最新更新 | av中文在线观看 | 亚洲黄色av网址 | 天堂av在线网址 | 亚洲黄网站| 涩涩网站在线 | www.av中文字幕.com | 丁香婷婷激情国产高清秒播 | 三级av片 | av综合站 | 九九九热精品免费视频观看 | 久久精品视频中文字幕 | 在线视频观看你懂的 | av超碰在线 | 免费影视大全推荐 | zzijzzij亚洲日本少妇熟睡 | 丰满少妇久久久 | 日韩在线视频观看免费 | 草久在线观看 | 91看片淫黄大片在线播放 | 天天操夜夜看 | www久久国产 | 成人在线免费看视频 | 成人久久 | 免费亚洲精品 | 久久欧洲视频 | 久草爱 | 日韩艹 | 国产 中文 日韩 欧美 | 欧美日韩aa | 国产免费a| 日韩欧美在线观看一区二区 | 婷婷精品在线 | 欧美性久久久久久 | 在线看日韩 | 99视频在线观看一区三区 | 青青河边草观看完整版高清 | 国产一区二区精品 | 免费高清无人区完整版 | 亚洲综合视频在线观看 | 中文字幕在线观看第三页 | 国产精品第二十页 | 97精品超碰一区二区三区 | 日日夜夜精品免费视频 | 亚洲一级特黄 | 一级片视频在线 | 欧美91精品久久久久国产性生爱 | 免费av观看网站 | 有码视频在线观看 | 久草在线官网 | 99色亚洲| 色爱区综合激月婷婷 | 天天曰天天 | 精品一区 精品二区 | 波多在线视频 | 在线色视频小说 | 国产 欧美 在线 | 欧美激情精品 | 国产精品系列在线观看 | 国产精品video爽爽爽爽 | 黄色的视频网站 | 日韩特级片 | 97人人澡人人添人人爽超碰 | 伊人六月| 久草免费色站 | 国模吧一区 | 久久一二三四 | 夜夜操综合网 | 欧美日本不卡 | 精品国产一区在线观看 | 四虎在线免费观看 | 综合久久婷婷 | 激情婷婷丁香 | 久久久久久久久久久综合 | 国产精品第三页 | 成人动漫一区二区三区 | 久久激情网站 | 国产精品露脸在线 | 欧美激情视频三区 | 日韩色中色 | 人人爽影院 | www.色五月 | 日本三级不卡视频 | 99精品热视频只有精品10 | 日本中文字幕网站 | 国产精品 亚洲精品 | 亚洲午夜久久久影院 | 日韩精品欧美精品 | 欧美男同视频网站 | 高清久久久 | 欧美在线视频第一页 | 中文字幕av全部资源www中文字幕在线观看 | 美女视频黄是免费的 | 伊人狠狠| 日日骑 | 中文字幕在线观看你懂的 | 九九久久久久99精品 | 九九99 | 久操视频在线 | 久久久久免费网 | 蜜桃视频日本 | 99热在线精品观看 | 狠狠狠的干 | av片一区二区| av千婊在线免费观看 | 亚洲三级黄色 | 国产精品中文 | 亚洲精品国产视频 | 成人毛片一区 | 毛片二区| 国产在线va | 色婷婷六月| 国产日韩欧美自拍 | 国产在线观看99 | 久草精品视频在线观看 | 欧美日韩xxxxx | 国产精品免费成人 | 色综合久久88色综合天天免费 | 国产精品女主播一区二区三区 | 91香蕉视频色版 | 西西444www大胆无视频 | av丝袜天堂 | 在线蜜桃视频 | 午夜视频99 | 四虎成人精品在永久免费 | 亚洲a成人v | 五月婷婷综合在线观看 | 亚洲 欧洲 国产 日本 综合 | 91在线播放综合 | 激情一区二区三区欧美 | 黄色精品一区 | 婷婷综合久久 | 天天草天天色 | 免费在线观看91 | 天天插综合 | 丰满少妇一级片 | www.天天综合 | 久久99亚洲网美利坚合众国 | 久久爱资源网 | 在线免费高清一区二区三区 | 国产精品国产亚洲精品看不卡15 | 五月天激情开心 | 国内视频一区二区 | 奇米影视8888在线观看大全免费 | 97香蕉久久国产在线观看 | 亚洲成人家庭影院 | 天天干天天操天天射 | 人人爱人人做人人爽 | 91人人澡人人爽 | 久久精品人人做人人综合老师 | 国产精品成人免费精品自在线观看 | 中文字幕免费一区 | 成人xxxx | 在线亚洲欧美视频 | 日韩在线观看a | 国产精品美女久久久久aⅴ 干干夜夜 | 色婷婷导航 | 亚洲精品国偷自产在线91正片 | 亚洲国产成人av网 | 就操操久久 | 99热这里只有精品1 av中文字幕日韩 | 99精品久久久久久久 | 精品视频9999| 91大神一区二区三区 | 中文字幕频道 | 91精品国产福利在线观看 | 免费一级片观看 | 欧美另类视频 | 国产精品普通话 | 国产成人久久精品77777综合 | 色就是色综合 | 国产精品视频专区 | 久久精品一二区 | 又黄又爽又色无遮挡免费 | 久久婷婷丁香 | 精品免费观看视频 | 麻豆免费在线视频 | 久久97超碰| 亚洲成人xxx | 在线免费观看黄色 | 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 国产精品专区在线观看 | 国产永久网站 | 日本 在线 视频 中文 有码 | 一级黄色片在线 | 久草在线观看资源 | www.玖玖玖 | av先锋中文字幕 | 欧美成年网站 | 久久99久久99免费视频 | 人人爽人人看 | 9999在线观看| 国产精品久久久久久久久久久久午夜 | 精品国产1区二区 | 国产精品美女999 | 国产精品久久影院 | 激情视频网页 | 日本爱爱片 | 人人干人人搞 | 国产精品一区二区免费看 | av在线官网 | 欧美韩日精品 | 久艹在线免费观看 | 国产人免费人成免费视频 | 中文字幕中文字幕 | 在线观看成人小视频 | 久久久久久久久久久免费av | 成人av一区二区兰花在线播放 | 亚洲第一中文字幕 | 久久综合狠狠 | 午夜精品久久久久久久99热影院 | 日本精品久久 | 一级黄视频 | 国产免费视频在线 | 免费一级片在线观看 | 亚洲污视频| 亚洲日本色 | 日日夜夜av | 91九色视频网站 | 四虎www com | 日韩视频免费在线 | 国产激情久久久 | 久久桃花网 | 日韩精品中文字幕在线不卡尤物 | 毛片随便看 | 中文字幕av电影下载 | 中文字幕资源站 | 亚洲永久国产精品 | 国产视频18 | 亚洲精品午夜久久久 | 婷婷黄色片| 久久久久国产一区二区三区四区 | 亚洲国产精品久久久 | 国产精品久久久久久久午夜片 | 在线视频成人 | 在线小视频国产 | 欧美性久久久久久 | 久久久久久国产精品亚洲78 | 手机成人在线 | 国产一区二区高清 | 免费a v网站 | 久久99国产综合精品免费 | 91精品1区2区 | 97碰在线视频| 91在线视频观看免费 | 亚洲a资源| 国产精品99久久久久久小说 | 字幕网在线观看 | 久久久久久久久久亚洲精品 | 九九免费在线视频 | 少妇视频一区 | av网站免费线看精品 | 在线免费观看羞羞视频 | 99亚洲国产 | 国产成人精品女人久久久 | 丁香六月婷 | 999成人国产 | 久久久久草 | 国产无套一区二区三区久久 | 久久影视中文字幕 | 中文字幕高清免费日韩视频在线 | 国产精品福利午夜在线观看 | 国产精品亚洲精品 | 91在线播放综合 | 亚洲色图av | 亚洲另类视频在线 | 在线视频一二区 | 亚洲国产美女久久久久 | 九九九在线观看视频 | 久久天天躁夜夜躁狠狠85麻豆 | 日本久久久久久科技有限公司 | 欧美二区在线播放 | 日韩.com| 中文字幕免费观看视频 | 国产一区播放 | 激情久久伊人 | 在线观看av片 | 91av电影在线 | 国产精品一区二区在线免费观看 | 久久人人爽人人爽人人片av免费 | 欧美国产一区在线 | 粉嫩av一区二区三区免费 | 久久国产精品免费 | av色综合| 四虎永久国产精品 | 手机看片国产日韩 | 91少妇精拍在线播放 | 2017狠狠干 | 免费观看久久久 | 波多野结衣在线观看视频 | 亚洲国产精品成人精品 | 九九色视频 | 免费在线国产黄色 | 亚洲一级片在线观看 | 亚洲高清视频在线观看 | av在线在线| 国产一区二区三区四区在线 | 午夜精品麻豆 | 国产一区二区三区四区大秀 | www.com.黄 | 日韩精品一区二区三区电影 | 日韩免费三级 | 精品久久久久久久久久久院品网 | 欧美一级日韩三级 | 久久久午夜精品理论片中文字幕 | 中文字幕精品三级久久久 | 久草视频观看 | 中文字幕在线观看免费观看 | 成人在线播放免费观看 | 波多野结衣在线观看一区二区三区 | 一级黄色在线免费观看 | 欧美日韩视频精品 | 不卡在线一区 | 波多野结衣在线观看一区二区三区 | 国产精品久久久久三级 | 精品三级av | 日韩欧美一区二区三区视频 | 欧洲精品二区 | 免费不卡中文字幕视频 | 99国产视频 | 在线观看中文字幕 | 亚洲午夜久久久影院 | 97在线免费 | 日韩a在线播放 | 国产另类xxxxhd高清 | 4438全国亚洲精品观看视频 | 国产精品久久久电影 | 国产美女视频免费观看的网站 | 91av视频在线免费观看 | 亚洲国产精品久久 | 91精品欧美一区二区三区 | 久久国产欧美日韩 | 久久观看免费视频 | av电影在线观看完整版一区二区 | 久草视频在线免费播放 | 亚洲二区精品 | 又黄又刺激的网站 | 国内精品久久久久久中文字幕 | 久久se视频| 波多野结衣在线播放一区 | 日本精品视频一区 | 国产手机免费视频 | 精品久久电影 | 日韩欧美一区二区三区视频 | 久草免费在线视频 | 欧美一二三区在线播放 | 日本黄色大片免费看 | 国产电影一区二区三区四区 | 国产不卡精品 | 免费看污黄网站 | 亚洲91中文字幕无线码三区 | 九九久| 国产精品视频内 | 国产亚洲精品无 | 99免费观看视频 | 9幺看片| 久久国产三级 | 日韩电影在线视频 | 欧美日韩不卡一区 | 韩国精品一区二区三区六区色诱 | 欧美一区二区三区在线视频观看 | 国产精品久久久区三区天天噜 | 久久99精品久久久久久清纯直播 | 欧美福利精品 | 97视频入口免费观看 | 久久国产精品一区二区三区四区 | 午夜视频日本 | jizz18欧美18 | 国产在线高清 | a精品视频| 成人中文字幕在线观看 | 九九视频免费观看视频精品 | 91在线免费观看网站 | www,黄视频 | 99色国产| 97精品一区 | 成人91在线观看 | 99精品乱码国产在线观看 | 国产精彩视频一区 | 福利视频导航网址 | 91精品资源 | 69国产精品成人在线播放 | av成人在线观看 | 日韩天堂在线观看 | 日韩欧美国产成人 | 国产又粗又猛又黄又爽 | 三级视频片 | 99re亚洲国产精品 | 久久久蜜桃一区二区 | 亚洲永久av| 高清av在线免费观看 | 黄色免费网| 国产亚洲精品久久久久久久久久 | 波多野结衣综合网 | 国产中文字幕免费 | 免费看黄色大全 | 国产99一区 | 国产亚洲精品久久久久久网站 | 91视频大全 | 中文字幕av日韩 | 国内外成人免费在线视频 | 在线观看中文 | 欧美狠狠色 | 丁香综合av | 日本不卡一区二区 | 国产中文在线视频 | 久久精品视频国产 | 综合婷婷 | 国产在线观看高清视频 | 国产精品毛片一区二区在线 | 日韩高清www | 欧美国产日韩中文 | 国产精品自产拍在线观看 | 在线一级片 | av网站在线免费观看 | 日韩高清不卡一区二区三区 | 日韩性久久 | 91av视频免费观看 | 国产玖玖在线 | 99国产精品免费网站 | 97精品视频在线 | 亚洲三级毛片 | 欧美精品在线观看免费 | 欧美在线一级片 | 午夜久久成人 | 黄色免费网 | 最近2019中文免费高清视频观看www99 | 日韩欧美在线中文字幕 | 国产精品黄色 | 在线观看av网 | 最近日本中文字幕 | 在线观看片 | 国产精品久久久久久久久久不蜜月 | 五月综合激情婷婷 | 91在线小视频 | 亚洲精品美女免费 | 精品999| 99激情网 | 天天舔天天射天天操 | 日韩色高清 | www·22com天天操 | 久久天天拍 | 中文字幕高清在线播放 | 天天天天天天操 | 日日摸日日 | 国产一级片观看 | h久久| av 一区二区三区 | 综合网色| 麻花传媒mv免费观看 | 久久爱资源网 | 国产精品成人一区二区三区吃奶 | 日日操天天操夜夜操 | 久久久久久影视 | 国产亚洲视频在线 | av在线超碰 | 天天爽天天射 | 四虎影院在线观看av | 视频二区在线 | 久久丁香 | 成人a视频片观看免费 | 99r在线精品 | 波多野结衣在线播放一区 | 免费在线播放av电影 | 亚洲一区二区视频 | 久草在线最新免费 | 天天摸天天舔天天操 | 天天操天天射天天添 | 色资源中文字幕 | 午夜三级福利 | 国产一级片免费视频 | 黄色av一区二区 | 国产一级特黄毛片在线毛片 | 黄色小视频在线观看免费 | 亚洲国产日韩一区 | 99国产精品一区二区 | 嫩草91影院 | 成人91在线| 永久免费看av | 中文字幕久久网 | 色综合www| 人人爽人人爽人人片 | 久草在线免费看视频 | 国产在线不卡精品 | 中文字幕在线播放视频 | 久久人人爽av | 亚洲乱码中文字幕综合 | 一区二区三区免费网站 | 国产在线中文 | 国产精品影音先锋 | 日日夜精品 | 久久99国产精品自在自在app | www夜夜操com| 91久久久久久国产精品 | 欧美日韩中文另类 | 视频在线观看入口黄最新永久免费国产 | 国产91欧美 | 久久麻豆精品 | 97高清免费视频 | 国产欧美日韩一区 | 亚洲1级片| 香蕉国产91 | 三级性生活视频 | 精品视频123区在线观看 | 又黄又刺激的网站 | 中文字幕91在线 | 日韩精品一区二区三区免费视频观看 | 激情综合色播五月 | 天堂av高清 | 国产精品区二区三区日本 | 久久成人综合 | 国产一区二区不卡在线 | 好看的国产精品视频 | 国产免费一区二区三区最新6 | 欧美一区二区三区在线视频观看 | 丁香资源影视免费观看 | 日韩精品第1页 | 亚洲第一成网站 | 成人av免费在线观看 | 国产亚州精品视频 | 四虎影视av | 成 人 免费 黄 色 视频 | 久久精品一区二区三区视频 | 97精品国产97久久久久久久久久久久 | 欧美二区三区91 | 天天插天天干 | 欧美久久久久久久久 | 成人av电影在线播放 | 欧美在线观看小视频 | 2023av| 欧美日韩成人一区 | 欧美成人黄色 | 国产一区国产二区在线观看 | 日韩av中文在线观看 | 国产少妇在线观看 | 精品综合久久久 | 久久av电影 | 日日干天天插 | 亚洲第一区在线观看 | 日本黄色片一区二区 | 国产精品黄网站在线观看 | 91系列在线 | 天天射日 | 久草亚洲视频 | www在线观看视频 | 国产成人福利在线 | 中文字幕免费播放 | 五月香视频在线观看 | 国产精品久久久久9999 | 色婷婷av一区 | 99精品福利 | 成人久久18免费网站图片 | 午夜精品一区二区三区在线视频 | 国产精品黑丝在线观看 | 免费久久99精品国产 | 天天综合操 | 国产精品成人在线观看 | 超碰人人干人人 | 一区二区三区高清不卡 | 国产在线观看你懂的 | 精品免费国产一区二区三区四区 | 国产精品1区2区在线观看 | 国产一级h | 视频在线日韩 | 欧美99热 | 综合天天网 | 国产精品黑丝在线观看 | 国产我不卡| 久久视频这里有久久精品视频11 | 午夜在线观看 | 天天爱天天 | 国产中文在线字幕 | 免费观看一级视频 | 日日操天天爽 | 丁香花在线视频观看免费 | 久久精品国产免费看久久精品 | 91尤物在线播放 | 亚洲区视频在线 | 免费看短 | 日本性久久 | 国产91九色视频 | 97视频免费在线 | 欧美日韩视频免费 | 人人添人人澡人人澡人人人爽 | 欧美另类色图 | 1区2区3区在线观看 三级动图 | 天天插日日射 | 久久天天躁狠狠躁夜夜不卡公司 | 特级a老妇做爰全过程 | 久久国产成人午夜av影院潦草 | 欧美亚洲免费在线一区 | 500部大龄熟乱视频使用方法 | 久久婷五月 | av在线免费观看网站 | 日韩欧美一二三 | 日韩精品一区二区三区视频播放 | 国产黄色av | 亚洲黄色免费 | 欧美福利网站 | 97视频在线观看播放 | 午夜精品福利在线 | 成人小视频在线 | 激情五月激情综合网 | 国产又粗又猛又黄又爽的视频 | 丁香国产视频 | 最新国产在线观看 | 国产伦精品一区二区三区无广告 | 黄色小说在线观看视频 | 久久久久久久久久久网 | 最新三级在线 | 亚洲国产三级 | 国产精品99页 | 国产日韩高清在线 | 91久久精品日日躁夜夜躁国产 | 欧美另类sm图片 | 国产剧在线观看片 | 911精品视频 | 久久99视频精品 | 亚洲毛片久久 | 亚洲黄在线观看 | 97在线观看视频 | a级免费观看 | 国产在线精品一区二区 | 欧美美女视频在线观看 | 97成人在线免费视频 | 在线黄色毛片 | 91成人在线网站 | 九九热免费在线观看 | 五月激情姐姐 | 日日干网 | 欧美日韩在线观看不卡 | 久久网站免费 | 欧美九九视频 | 精品视频www | 天天操天天操天天操天天操天天操天天操 | 久草视频中文 | 国产福利午夜 | 国产一二区视频 | 国产传媒一区在线 | 中文字幕日韩精品有码视频 | 99精品国产一区二区 | 天天激情天天干 | 97天天综合网 | 久草在线在线精品观看 | 国产很黄很色的视频 | 久久99这里只有精品 | www.av免费观看| 精品一区二区三区香蕉蜜桃 | 成人小视频在线免费观看 | 国产亚洲精品久久网站 | 日韩三区在线 | 玖玖视频精品 | 久久午夜影视 | 久久草av | 久久你懂得 | 久香蕉 | 天天干天天干 | 久久精品爱视频 | 亚洲成av人片在线观看香蕉 | 欧美一级片| 欧美资源 | 一级免费av | 丝袜av网站| 欧美日韩一区二区在线观看 | av播放在线| 午夜在线观看影院 | 色综合夜色一区 | 成人在线免费观看视视频 | 国产精品欧美日韩在线观看 | 国产专区视频在线观看 | 黄色软件视频网站 | 亚洲国产精品99久久久久久久久 | 国产无限资源在线观看 | 日韩久久精品一区二区三区下载 | 伊人狠狠 | 亚洲精品国偷拍自产在线观看 | 青青视频一区 | 91精品伦理 | 中文一区二区三区在线观看 | 99视频偷窥在线精品国自产拍 | 日本黄色免费大片 | 国产精品成人av电影 | 色操插| 麻豆国产在线播放 | 97色视频在线| 一区二区三区四区精品 | 久久综合九色综合欧美就去吻 | 国产精品9999久久久久仙踪林 | 99视频+国产日韩欧美 | av中文在线 | 色婷婷综合久久久久中文字幕1 | 成人毛片久久 | 91精品视屏 | 久久久久久久久久久久av | 99免费国产| 欧美亚洲免费在线一区 | 黄色大片入口 | 久色网| 久久久久成人精品亚洲国产 | 久久婷婷久久 | 欧美在线aa | 久久亚洲私人国产精品va | 手机看片中文字幕 | 欧美一区二区在线刺激视频 | 久久免费av电影 | 天天操人人要 | 国产九色视频在线观看 | 成人黄色中文字幕 | 欧美精品一区在线 | 国产精品久久久久免费观看 | 久久免费黄色大片 | 西西4444www大胆艺术 | 日韩欧美视频二区 | 狠狠gao| 国产手机在线观看 | 91成人黄色 | 亚洲在线网址 | 国产在线观看免费av | 婷婷综合伊人 | 国产黄色片网站 | 在线免费高清视频 | 亚洲专区在线 | 91最新在线观看 | 欧美 日韩 国产 成人 在线 |