以上就是给各位分享在pygame中将滚动添加到平台游戏,其中也会对pygame滚动条进行解释,同时本文还将给你拓展Clock.schedule_interval()在pygame中有效还是仅在pyga
以上就是给各位分享在pygame中将滚动添加到平台游戏,其中也会对pygame滚动条进行解释,同时本文还将给你拓展Clock.schedule_interval()在pygame中有效还是仅在pygame中为零?、Pygame Zero:如何在让玩家进入“游戏结束”后向 Pygame Zero 添加 Surface、pygame中pygame.sprite.groupcollide的知识、pygame中的多人游戏程序在添加一些代码后运行非常慢等相关知识,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:- 在pygame中将滚动添加到平台游戏(pygame滚动条)
- Clock.schedule_interval()在pygame中有效还是仅在pygame中为零?
- Pygame Zero:如何在让玩家进入“游戏结束”后向 Pygame Zero 添加 Surface
- pygame中pygame.sprite.groupcollide的知识
- pygame中的多人游戏程序在添加一些代码后运行非常慢
在pygame中将滚动添加到平台游戏(pygame滚动条)
好的,所以我在下面包含了我项目的代码,我只是在做一些平台游戏方面对pygame做一些试验。我试图弄清楚如何按照播放器进行一些非常简单的滚动,因此播放器是相机的中心,它会弹跳/跟随他。谁能帮我?
import pygamefrom pygame import *WIN_WIDTH = 800WIN_HEIGHT = 640HALF_WIDTH = int(WIN_WIDTH / 2)HALF_HEIGHT = int(WIN_HEIGHT / 2)DISPLAY = (WIN_WIDTH, WIN_HEIGHT)DEPTH = 32FLAGS = 0CAMERA_SLACK = 30def main(): global cameraX, cameraY pygame.init() screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH) pygame.display.set_caption("Use arrows to move!") timer = pygame.time.Clock() up = down = left = right = running = False bg = Surface((32,32)) bg.convert() bg.fill(Color("#000000")) entities = pygame.sprite.Group() player = Player(32, 32) platforms = [] x = y = 0 level = [ "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP", "P P", "P P", "P P", "P P", "P P", "P P", "P P", "P PPPPPPPPPPP P", "P P", "P P", "P P", "P P", "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",] # build the level for row in level: for col in row: if col == "P": p = Platform(x, y) platforms.append(p) entities.add(p) if col == "E": e = ExitBlock(x, y) platforms.append(e) entities.add(e) x += 32 y += 32 x = 0 entities.add(player) while 1: timer.tick(60) for e in pygame.event.get(): if e.type == QUIT: raise SystemExit, "QUIT" if e.type == KEYDOWN and e.key == K_ESCAPE: raise SystemExit, "ESCAPE" if e.type == KEYDOWN and e.key == K_UP: up = True if e.type == KEYDOWN and e.key == K_DOWN: down = True if e.type == KEYDOWN and e.key == K_LEFT: left = True if e.type == KEYDOWN and e.key == K_RIGHT: right = True if e.type == KEYDOWN and e.key == K_SPACE: running = True if e.type == KEYUP and e.key == K_UP: up = False if e.type == KEYUP and e.key == K_DOWN: down = False if e.type == KEYUP and e.key == K_RIGHT: right = False if e.type == KEYUP and e.key == K_LEFT: left = False if e.type == KEYUP and e.key == K_RIGHT: right = False # draw background for y in range(32): for x in range(32): screen.blit(bg, (x * 32, y * 32)) # update player, draw everything else player.update(up, down, left, right, running, platforms) entities.draw(screen) pygame.display.update()class Entity(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self)class Player(Entity): def __init__(self, x, y): Entity.__init__(self) self.xvel = 0 self.yvel = 0 self.onGround = False self.image = Surface((32,32)) self.image.fill(Color("#0000FF")) self.image.convert() self.rect = Rect(x, y, 32, 32) def update(self, up, down, left, right, running, platforms): if up: # only jump if on the ground if self.onGround: self.yvel -= 10 if down: pass if running: self.xvel = 12 if left: self.xvel = -8 if right: self.xvel = 8 if not self.onGround: # only accelerate with gravity if in the air self.yvel += 0.3 # max falling speed if self.yvel > 100: self.yvel = 100 if not(left or right): self.xvel = 0 # increment in x direction self.rect.left += self.xvel # do x-axis collisions self.collide(self.xvel, 0, platforms) # increment in y direction self.rect.top += self.yvel # assuming we''re in the air self.onGround = False; # do y-axis collisions self.collide(0, self.yvel, platforms) def collide(self, xvel, yvel, platforms): for p in platforms: if pygame.sprite.collide_rect(self, p): if isinstance(p, ExitBlock): pygame.event.post(pygame.event.Event(QUIT)) if xvel > 0: self.rect.right = p.rect.left print "collide right" if xvel < 0: self.rect.left = p.rect.right print "collide left" if yvel > 0: self.rect.bottom = p.rect.top self.onGround = True self.yvel = 0 if yvel < 0: self.rect.top = p.rect.bottomclass Platform(Entity): def __init__(self, x, y): Entity.__init__(self) self.image = Surface((32, 32)) self.image.convert() self.image.fill(Color("#DDDDDD")) self.rect = Rect(x, y, 32, 32) def update(self): passclass ExitBlock(Platform): def __init__(self, x, y): Platform.__init__(self, x, y) self.image.fill(Color("#0033FF"))if __name__ == "__main__": main()
答案1
小编典典绘制实体时,你需要将偏移量应用于实体的位置。我们称这个偏移量为 a camera
,因为这是我们想要达到的效果。
首先,我们无法使用drawSprite
群组的功能,因为Sprite不
需要知道其位置(rect)
并非要在屏幕上绘制的位置(最后,我们ll对该Group
类进行子类化,并重新实现它draw以了解摄像头,但让我们开始慢一点)。
让我们从创建一个Camera
类开始,以保存要应用于实体位置的偏移量的状态:
class Camera(object): def __init__(self, camera_func, width, height): self.camera_func = camera_func self.state = Rect(0, 0, width, height) def apply(self, target): return target.rect.move(self.state.topleft) def update(self, target): self.state = self.camera_func(self.state, target.rect)
这里要注意一些事情:
我们需要存储摄像机的位置以及水平的宽度和高度(以像素为单位)(因为我们要停止在水平边缘进行滚动)。我曾经使用a Rect
来存储所有这些信息,但是你可以轻松地使用一些字段。
使用Rect
派上用场的apply
功能。在这里我们重新计算实体在屏幕上的位置以应用滚动。
每个主循环迭代一次,我们需要更新摄影机的位置,因此有了update
功能。它只是通过调用camera_func
函数来改变状态,这将为我们完成所有艰苦的工作。我们稍后实施。
让我们创建一个摄影机的实例:
for row in level: ...total_level_width = len(level[0])*32 # calculate size of level in pixelstotal_level_height = len(level)*32 # maybe make 32 an constantcamera = Camera(*to_be_implemented*, total_level_width, total_level_height)entities.add(player)...
并更改我们的主循环:
# draw backgroundfor y in range(32): ...camera.update(player) # camera follows player. Note that we could also follow any other sprite# update player, draw everything elseplayer.update(up, down, left, right, running, platforms)for e in entities: # apply the offset to each entity. # call this for everything that should scroll, # which is basically everything other than GUI/HUD/UI screen.blit(e.image, camera.apply(e)) pygame.display.update()
我们的摄像头课程已经非常灵活,但是非常简单。它可以使用不同种类的滚动(通过提供不同的camera_func
功能),并且可以跟随任何变态的精灵,而不仅仅是播放器。你甚至可以在运行时更改此设置。
现在用于实施camera_func
。一种简单的方法是将播放器(或我们要跟随的任何实体)居中放在屏幕上,实现很简单:
def simple_camera(camera, target_rect): l, t, _, _ = target_rect # l = left, t = top _, _, w, h = camera # w = width, h = height return Rect(-l+HALF_WIDTH, -t+HALF_HEIGHT, w, h)
我们只是将放在位置target,然后加上一半的总屏幕尺寸。你可以通过以下方式创建相机来尝试:
camera = Camera(simple_camera, total_level_width, total_level_height)
到目前为止,一切都很好。但是也许我们不想看到关卡外面的黑色背景?怎么样:
def complex_camera(camera, target_rect): # we want to center target_rect x = -target_rect.center[0] + WIN_WIDTH/2 y = -target_rect.center[1] + WIN_HEIGHT/2 # move the camera. Let''s use some vectors so we can easily substract/multiply camera.topleft += (pygame.Vector2((x, y)) - pygame.Vector2(camera.topleft)) * 0.06 # add some smoothness coolnes # set max/min x/y so we don''t see stuff outside the world camera.x = max(-(camera.width-WIN_WIDTH), min(0, camera.x)) camera.y = max(-(camera.height-WIN_HEIGHT), min(0, camera.y)) return camera
在这里,我们仅使用min/ max函数以确保我们不会向外滚动。
像这样创建相机来尝试一下:
camera = Camera(complex_camera, total_level_width, total_level_height)
我们的最终滚动效果有点动画:
在此处输入图片说明
再次是完整的代码。注意我更改了一些内容:
- 级别更大,并拥有更多平台
- 使用python 3
- 使用精灵组来处理相机
- 重构了一些重复的代码
- 由于Vector2 / 3现在很稳定,因此请使用它们来简化数学运算
- 摆脱丑陋的事件处理代码,
pygame.key.get_pressed
而改用
#! /usr/bin/pythonimport pygamefrom pygame import *SCREEN_SIZE = pygame.Rect((0, 0, 800, 640))TILE_SIZE = 32 GRAVITY = pygame.Vector2((0, 0.3))class CameraAwareLayeredUpdates(pygame.sprite.LayeredUpdates): def __init__(self, target, world_size): super().__init__() self.target = target self.cam = pygame.Vector2(0, 0) self.world_size = world_size if self.target: self.add(target) def update(self, *args): super().update(*args) if self.target: x = -self.target.rect.center[0] + SCREEN_SIZE.width/2 y = -self.target.rect.center[1] + SCREEN_SIZE.height/2 self.cam += (pygame.Vector2((x, y)) - self.cam) * 0.05 self.cam.x = max(-(self.world_size.width-SCREEN_SIZE.width), min(0, self.cam.x)) self.cam.y = max(-(self.world_size.height-SCREEN_SIZE.height), min(0, self.cam.y)) def draw(self, surface): spritedict = self.spritedict surface_blit = surface.blit dirty = self.lostsprites self.lostsprites = [] dirty_append = dirty.append init_rect = self._init_rect for spr in self.sprites(): rec = spritedict[spr] newrect = surface_blit(spr.image, spr.rect.move(self.cam)) if rec is init_rect: dirty_append(newrect) else: if newrect.colliderect(rec): dirty_append(newrect.union(rec)) else: dirty_append(newrect) dirty_append(rec) spritedict[spr] = newrect return dirty def main(): pygame.init() screen = pygame.display.set_mode(SCREEN_SIZE.size) pygame.display.set_caption("Use arrows to move!") timer = pygame.time.Clock() level = [ "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP", "P P", "P P", "P P", "P PPPPPPPPPPP P", "P P", "P P", "P P", "P PPPPPPPP P", "P P", "P PPPPPPP P", "P PPPPPP P", "P P", "P PPPPPPP P", "P P", "P PPPPPP P", "P P", "P PPPPPPPPPPP P", "P P", "P PPPPPPPPPPP P", "P P", "P P", "P P", "P P", "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",] platforms = pygame.sprite.Group() player = Player(platforms, (TILE_SIZE, TILE_SIZE)) level_width = len(level[0])*TILE_SIZE level_height = len(level)*TILE_SIZE entities = CameraAwareLayeredUpdates(player, pygame.Rect(0, 0, level_width, level_height)) # build the level x = y = 0 for row in level: for col in row: if col == "P": Platform((x, y), platforms, entities) if col == "E": ExitBlock((x, y), platforms, entities) x += TILE_SIZE y += TILE_SIZE x = 0 while 1: for e in pygame.event.get(): if e.type == QUIT: return if e.type == KEYDOWN and e.key == K_ESCAPE: return entities.update() screen.fill((0, 0, 0)) entities.draw(screen) pygame.display.update() timer.tick(60)class Entity(pygame.sprite.Sprite): def __init__(self, color, pos, *groups): super().__init__(*groups) self.image = Surface((TILE_SIZE, TILE_SIZE)) self.image.fill(color) self.rect = self.image.get_rect(topleft=pos)class Player(Entity): def __init__(self, platforms, pos, *groups): super().__init__(Color("#0000FF"), pos) self.vel = pygame.Vector2((0, 0)) self.onGround = False self.platforms = platforms self.speed = 8 self.jump_strength = 10 def update(self): pressed = pygame.key.get_pressed() up = pressed[K_UP] left = pressed[K_LEFT] right = pressed[K_RIGHT] running = pressed[K_SPACE] if up: # only jump if on the ground if self.onGround: self.vel.y = -self.jump_strength if left: self.vel.x = -self.speed if right: self.vel.x = self.speed if running: self.vel.x *= 1.5 if not self.onGround: # only accelerate with gravity if in the air self.vel += GRAVITY # max falling speed if self.vel.y > 100: self.vel.y = 100 print(self.vel.y) if not(left or right): self.vel.x = 0 # increment in x direction self.rect.left += self.vel.x # do x-axis collisions self.collide(self.vel.x, 0, self.platforms) # increment in y direction self.rect.top += self.vel.y # assuming we''re in the air self.onGround = False; # do y-axis collisions self.collide(0, self.vel.y, self.platforms) def collide(self, xvel, yvel, platforms): for p in platforms: if pygame.sprite.collide_rect(self, p): if isinstance(p, ExitBlock): pygame.event.post(pygame.event.Event(QUIT)) if xvel > 0: self.rect.right = p.rect.left if xvel < 0: self.rect.left = p.rect.right if yvel > 0: self.rect.bottom = p.rect.top self.onGround = True self.yvel = 0 if yvel < 0: self.rect.top = p.rect.bottomclass Platform(Entity): def __init__(self, pos, *groups): super().__init__(Color("#DDDDDD"), pos, *groups)class ExitBlock(Platform): def __init__(self, pos, *groups): super().__init__(Color("#0033FF"), pos, *groups)if __name__ == "__main__": main()
Clock.schedule_interval()在pygame中有效还是仅在pygame中为零?
Current Working Directory
在pygame中不存在。请参阅pygame.time
模块。 const time = ['00:00','00:30','01:00','01:30'];
const nums = [1.99,5.11,2.99,3.45 ];
const newArray = [];
time.forEach((element,index) => {
newArray.push({
time: element,cost: nums[index]
})
})
console.log(newArray)
是pygame零中类schedule_interval
的一种方法。参见Pygame Zero - Built-in Objects。
在pygame中,您可以创建一个计时器事件。请参阅问题Python 3.8 pygame timer?或Countdown timer in Pygame的答案。
Pygame Zero:如何在让玩家进入“游戏结束”后向 Pygame Zero 添加 Surface
如何解决Pygame Zero:如何在让玩家进入“游戏结束”后向 Pygame Zero 添加 Surface?
我目前正在为学校项目制作游戏。基本上:角色被一个不断向他移动的矩形猎杀。现在,每当它发生碰撞时,我都希望在屏幕中间显示一个带有文本“Gameover”的大红色框。但是 Rects 只能在边框上着色,在 Pygame 文档中,我不明白我首先需要做什么才能使 Surface 以我想要的方式工作。
现在我的问题是:一旦角色与敌人碰撞以发出“游戏结束”的信号,我如何实现一个红色的 Surface 弹出。
我想到的是在 draw 函数中设置一个“if”语句,一旦发生碰撞,该语句就会设置为 true,以便仅在玩家进入游戏结束时绘制表面。
类似于:(以防有人想知道:“Tesbold”是玩家角色,“追随者”是猎杀玩家的对象)
def draw():
screen.clear()
screen.fill((200,200,200))
Tesbold.draw()
Follower.draw()
screen.surface = pygame.display.set_mode((0,0),pygame.FULLSCREEN)
if Gameover = True:
(Draw Red Box with Text "Gameover" in the middle of the screen)
@H_301_10@
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
pygame中pygame.sprite.groupcollide的知识
在照例程做pygame外星人小游戏时遇到精灵组碰撞检测的问题,不是很明白。以下是pygame.sprite.
groupcollide
()的官方文档
This will find collisions between all the Sprites in two groups. Collision is determined by comparing the Sprite.rect
attribute of each Sprite or by using the collided function if it is not None.
Every Sprite inside group1 is added to the return dictionary. The value for each item is the list of Sprites in group2 that intersect.
If either dokill argument is True, the colliding Sprites will be removed from their respective Group.
The collided argument is a callback function used to calculate if two sprites are colliding. It should take two sprites as values and return a bool value indicating if they are colliding. If collided is not passed, then all sprites must have a "rect" value, which is a rectangle of the sprite area, which will be used to calculate the collision.
说的我有点云里雾里,运行游戏程序打印一下pygame.sprite.
groupcollide
()的输出(为方便测试这里采用了大子弹)
1 {}
2 {<Bullet sprite(in 0 groups)>: [<Alien sprite(in 0 groups)>]}
3 {<Bullet sprite(in 0 groups)>: [<Alien sprite(in 0 groups)>, <Alien sprite(in 0 groups)>, <Alien sprite(in 0 groups)>, <Alien sprite(in 0 groups)>, <Alien sprite(in 0 groups)>, <Alien sprite(in 0 groups)>]}
可以看出pygame.sprite.
groupcollide
()的返回值会有这三种。精灵组无碰撞发生则返回空字典({}的布尔值是Flase),发生碰撞则返回字典,其中子弹为键,外星人为值。每当检测到碰撞发生都会返回一个这样的字典。这样以下增加得分的代码也就很好理解了。
1 collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
2 if collisions:
3 stats.score += ai_settings.alien_points
pygame中的多人游戏程序在添加一些代码后运行非常慢
您的套接字处理代码(可能)是导致速度下降的原因。 socket.recv()
正在等待数据到达。当然,您可以将套接字设置为非阻塞读取,但是仍然存在是否已到达完整数据包的问题。
我会将您的代码转换为使用固定的数据包大小。与其发送可变长度的颜色名称,不如发送一个颜色元组。发送[250 250 210],然后发送“浅金黄色”要快得多;)我想您可以只使用[red ]
和[blue]
。
一旦您确定了数据包的大小,则可以准确地知道何时有新数据包到达,而不是说半个数据包。当然,对于本地网络上没有微小碎片的小数据包来说,这并不是真正的问题。但是数据量增加,网络拓扑发生变化,出现碎片。
我喜欢使用select
模块(紧密模拟同名的C系统函数)来知道是否有任何数据到达套接字,如果没有任何内容,则只需返回主程序循环。但是,如果有可用数据,则将任何内容读入缓冲区。这为您提供了一个程序模型,您可以在其中读取任何已到达的内容(大多数情况下什么都不读取),并且如果“到达的”缓冲区中有足够的字节,则取出足够的字节以形成完整的数据包。它简单,强大且运行良好。
给定功能:
import socket
import select
def socketReadIfAvailable( read_socket:socket.socket,packet_buffer:bytearray,amount:int=1,timeout:float=0 ):
""" Given an open socket,and a packet-buffer,return a packet if one is available.
Returns a tuple of:
None - if no packet is available
data-packet - (of <amount> bytes) if data is available (of <amount> bytes length)
-1 - if the socket has closed
AND the current packet-buffer """
result = None
# If we already have enough data buffered,don't re-fetch
if ( len( packet_buffer ) >= amount ):
bytes_read = packet_buffer[0:amount]
packet_buffer = packet_buffer[amount:]
result = bytes_read
else:
# There's not enough data,so try to read some,but only for <timeout> seconds
# if timeout is zero,just read whatever is sitting in the socket buffer already
read_events_on = [ read_socket ]
(read_list,write_list,except_list) = select.select( read_events_on,[],timeout )
if ( len( read_list ) > 0 ):
# New data arrived,read it
incoming = read_socket.recv( 8192 )
if ( len( incoming ) == 0 ):
# No data arrived,meaning the socket has closed
result = -1
else:
#print("%d bytes Rx'd" % ( len( incoming ) ) )
#print("%d bytes buffered" % ( len( packet_buffer ) ) )
packet_buffer += incoming # new bytes arrived,is there enough data now?
if ( len( packet_buffer ) >= amount ):
bytes_read = packet_buffer[0:amount]
packet_buffer = packet_buffer[amount:]
result = bytes_read
return result,packet_buffer
一个11字节的固定大小的数据包(RGB颜色为3字节,每个坐标为4字节),您的读取代码可能类似于:
packet_buffer = bytearray()
...
pygame.display.flip()
packet,packet_buffer = socketReadIfAvailable( s,packet_buffer,11 )
if ( packet != None ):
if ( packet == -1 ):
# TODO: handle Socket has closed
packet_buffer = bytearray() # clear buffer
else:
colour = struct.unpack( "!BBB",packet[0:3] ) # use network byte-order
x,y = struct.unpack( "!2i",packet[3:11] )
当然,如果您不想使用固定大小,则可以仅查看是否有任何数据到达,然后try:
对其进行解包(或整理),并希望获得最好的结果。不过,这效率相对较低。
编辑
通常我会尽量不成为免费的代码编写服务,但是我对有趣的外观原型游戏深信不疑;)
好吧,我不确定您的游戏应该如何运作。我发现整个red
和blue
变量集令人困惑。我认为您应该对代码进行重新设计,以使其具有不带GUI的单个服务器,而只是在客户端之间分流更新的位置。然后,您可以拥有一个游戏代码,其中两个玩家(或 N 玩家)都连接到该服务器。这也会从您的代码中删除red
与blue
VS x
,留下“本地”和“其他”(或您想称呼它们的任何东西)。
我修改了您的代码,使其仅在y
和import pygame
import time
import random
import socket
import struct
import select
network_buffer = bytearray()
def socketReadIfAvailable( read_socket:socket.socket,return a packet if one is available.
Returns a tuple of:
None - if no packet is available
data-packet - (of <amount> bytes) if data is available (of <amount> bytes length)
-1 - if the socket has closed
AND the current packet-buffer """
result = None
# If we already have enough data buffered,packet_buffer
pygame.init()
s = socket.socket()
port = 12345
s.bind(('',port))
s.listen(5)
c,addr = s.accept()
print ("Socket Up and running with a connection from",addr)
screen = pygame.display.set_mode( ( 1200,960 ) )
pygame.display.set_caption("Maze Server")
blocks = [(50,50,200,25),(200,25,250),(300,(50,200),(250,100,250,(350,225,(75,325,(25,150,(100,75,100),375,175,425,75),500,450,150),(150,550,300,175),600,(0,400,650,(125,625,750,10000,28),(1350,16,10000),(225,125),(175,700,(275,125,50),(500,300),(400,225),(425,(450,275),500),(550,475),575,(325,(375,(475,(525,(600,525,(650,(850,475,675,(700,725,(900,(950,(800,275,(750,(875,350,(575,(925,(1025,(1050,(1125,375),(1075,(1175,(1150,(1300,(1250,(1000,(1100,(1200,25)
]
x,y = 0,0
sent_x,sent_y = -1,-1
walls = [pygame.Rect(r) for r in blocks]
Svel = 5
Hvel = 5
red = pygame.Rect(225,25)
blue = pygame.Rect(1100,25)
SeekChoice = random.randint(1,2)
if SeekChoice == 1:
seeker = "red"
Snum = 2
if SeekChoice == 2:
seeker = "blue"
Snum = 1
Num = 0
c.send(struct.pack("2i",SeekChoice,Num))
RedScore = 0
BlueScore = 0
RTime = 0
BTime = 0
running = True
font = pygame.font.Font(None,60)
RedWin = font.render("RED IS WINNER!",(255,0))
BlueWin = font.render("BLUE IS WINNER!",255))
while running:
### Receive a fixed-size packet from the client (if any)
### Client only sends us an x,y
#buf = c.recv(8,socket.MSG_WAITALL)
buf,network_buffer = socketReadIfAvailable( s,network_buffer,8 ) # 8 bytes in a full packet
if ( buf != None ): # *IF* a packet was received
if ( buf == -1 ):
print( "Client disconnected" )
network_buffer = bytearray()
# TODO
else:
# A packet was received,unpack it
x,y = struct.unpack( "2i",buf ) # unpack the co-ordinates
print( "Rx: (%d,%d)" % ( x,y ) )
red = pygame.Rect(x,y,25)
if RedScore >= 20:
screen.fill([255,255,255])
screen.blit(RedWin,[500,250])
pygame.display.flip()
time.sleep(10)
pygame.quit()
running = False
if BlueScore >= 20:
screen.fill([255,255])
screen.blit(BlueWin,250])
pygame.display.flip()
time.sleep(10)
pygame.quit()
running = False
RTime += 1
BTime += 1
x1 = red.x
y1 = red.y
x2 = blue.x
y2 = blue.y
if seeker == "red":
RTime = 0
elif RTime >= 2000:
RTime = 0
RedScore += 1
if seeker == "blue":
BTime = 0
elif BTime >= 2000:
BTime = 0
BlueScore += 1
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
blue.x = max(blue.x - Svel,0)
for wall in walls:
if blue.colliderect(wall):
blue.left = max(blue.left,wall.right)
if keys[pygame.K_RIGHT]:
blue.x = min(blue.x + Svel,1341)
for wall in walls:
if blue.colliderect(wall):
blue.right = min(blue.right,wall.left)
if keys[pygame.K_UP]:
blue.y = max(blue.y - Svel,0)
for wall in walls:
if blue.colliderect(wall):
blue.top = max(blue.top,wall.bottom)
if keys[pygame.K_DOWN]:
blue.y = min(blue.y + Svel,743)
for wall in walls:
if blue.colliderect(wall):
blue.bottom = min(blue.bottom,wall.top)
screen.fill([0,0])
#pygame.draw.circle(screen,[255,255],(x1+12,y1+12),125)
pygame.draw.circle(screen,(x2+12,y2+12),125)
for wall in walls:
pygame.draw.rect(screen,[0,0],wall)
#pygame.draw.rect(screen,red)
pygame.draw.rect(screen,blue)
# if seeker == "red":
# pygame.draw.rect(screen,(red.x+7,red.y+7,10,10))
# if seeker == "blue":
# pygame.draw.rect(screen,(blue.x+7,blue.y+7,10))
pygame.draw.rect(screen,10))
pygame.display.flip()
if red.colliderect(blue):
if seeker == "red":
print ("red/blue")
seeker = "blue"
Snum = 1
BTime = 0
RedScore += 2
BlueScore -= 3
red = pygame.Rect(225,25)
blue = pygame.Rect(1166,334,25)
elif seeker == "blue":
print ("blue/red")
Snum = 2
RTime = 0
seeker = "red"
BlueScore += 2
RedScore -= 3
red = pygame.Rect(225,25)
### Pack and send the fixed-size data to the client
### But only if the position x,y has changed
if ( sent_x != blue.x or sent_y != blue.y ):
seeker_name = "%-12s" % ( seeker ) # pad to 12 spaces,this never changes,move outside loop
seeker_name = seeker_name.encode() # this too
c.send( bytes( seeker_name ) ) # send the colour-name padded to 12 letters
c.send( struct.pack("2i",blue.x,blue.y ) ) # send the x,y
sent_x = blue.x
sent_y = blue.y
print( "Tx: [%s],(%d,%d)" % ( seeker,sent_x,sent_y ) )
坐标更改时才发送位置。无需使用相同的不变坐标将网络垃圾邮件每秒60次。
还可以考虑添加注释,有时还可以在代码中添加空白行,这使跟踪变得更加容易。我将此添加到其中一个文件中。
服务器:
import pygame
import time
import random
import socket
import struct
pygame.init()
import select
network_buffer = bytearray()
def socketReadIfAvailable( read_socket:socket.socket,packet_buffer
s = socket.socket()
s.connect(('127.0.0.1',12345))
screen = pygame.display.set_mode( ( 1200,960 ) )
pygame.display.set_caption("Maze Client")
blocks = [(50,25)
]
sent_x,25)
buf = s.recv(8,socket.MSG_WAITALL)
SeekChoice,Num = struct.unpack("2i",buf)
if SeekChoice == 1:
seeker = "red"
Snum = 1
if SeekChoice == 2:
seeker = "blue"
Snum = 2
RedScore = 0
BlueScore = 0
RTime = 0
BTime = 0
running = True
font = pygame.font.Font(None,255))
#screen.fill([255,255])
#pygame.draw.circle(screen,(red.x+12,red.y+12),75)
#pygame.draw.circle(screen,(blue.x+12,blue.y+12),75)
#for wall in walls:
# pygame.draw.rect(screen,wall)
#pygame.draw.rect(screen,red)
#pygame.draw.rect(screen,blue)
#if seeker == "red":
# pygame.draw.rect(screen,10))
#if seeker == "blue":
# pygame.draw.rect(screen,10))
#pygame.display.flip()
while running:
# if Snum == 1:
# seeker = "red"
# if Snum == 2:
# seeker = "blue"
### Send the x,y position only if it's changed
if ( sent_x != red.x or sent_y != red.y ):
s.send(struct.pack("2i",red.x,red.y))
sent_x = red.x
sent_y = red.y
print( "Tx: (%d,%d)" % ( sent_x,sent_y ) )
if RedScore >= 20:
screen.fill([255,250])
pygame.display.flip()
time.sleep(10)
pygame.quit()
running = False
RTime += 1
BTime += 1
if seeker == "red":
RTime = 0
elif RTime >= 2000:
RTime = 0
RedScore += 1
if seeker == "blue":
BTime = 0
elif BTime >= 2000:
BTime = 0
BlueScore += 1
# Handle Events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
running = False
# Handle movement keys
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
red.x = max(red.x - Svel,0)
for wall in walls:
if red.colliderect(wall):
red.left = max(red.left,wall.right)
if keys[pygame.K_RIGHT]:
red.x = min(red.x + Svel,1341)
for wall in walls:
if red.colliderect(wall):
red.right = min(red.right,wall.left)
if keys[pygame.K_UP]:
red.y = max(red.y - Svel,0)
for wall in walls:
if red.colliderect(wall):
red.top = max(red.top,wall.bottom)
if keys[pygame.K_DOWN]:
red.y = min(red.y + Svel,743)
for wall in walls:
if red.colliderect(wall):
red.bottom = min(red.bottom,wall.top)
# Paint the screen
screen.fill([0,0])
pygame.draw.circle(screen,125)
#pygame.draw.circle(screen,wall)
pygame.draw.rect(screen,red)
#pygame.draw.rect(screen,10))
pygame.display.flip()
#seeker = s.recv(1024)
#seeker = seeker.decode()
#buf = s.recv(8,socket.MSG_WAITALL)
#x,y = struct.unpack("2i",buf)
### Receive a fixed-size packet from the server (if any)
### Server sends a 12-letter name,and x,y
buf,20 ) # 20 bytes in a full packet
if ( buf != None ): # *IF* a packet was received
if ( buf == -1 ):
print( "Client disconnected" )
network_buffer = bytearray()
# TODO
else:
# A packet was received,unpack it
seeker = buf[0:12].decode( "utf-8" ) # unpack the 12-letter (padded) name
seeker = seeker.strip()
x,buf[12:20] ) # unpack the co-ordinates
blue = pygame.Rect(x,25)
print( "Rx: [%s] at (%d,x,y ) )
red = pygame.Rect(red.x,red.y,25)
客户:
socketReadIfAvailable()
很显然,您可以将blocks
移到一个公共文件中,也许也移到class Manager:
def __init__(self,cls): self.cls=cls
# …
class PreManager:
def __get__(self,cls,obj): return Manager(cls)
class Model:
objects=PreManager()
中。
关于在pygame中将滚动添加到平台游戏和pygame滚动条的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于Clock.schedule_interval()在pygame中有效还是仅在pygame中为零?、Pygame Zero:如何在让玩家进入“游戏结束”后向 Pygame Zero 添加 Surface、pygame中pygame.sprite.groupcollide的知识、pygame中的多人游戏程序在添加一些代码后运行非常慢的相关知识,请在本站寻找。
本文标签: