乐趣区

关于游戏开发:2d游戏设计pygame-游戏开发自主开发

此次作业是应用 pygame 模块自主设计一款 2D 游戏。

此次制作的游戏灵感来源于 jumpKing,这是一款发售于 steam 的高技术游戏。

咱们抉择了他们的操作形式:需 A、D 键来管制人物的挪动,以及空格键使人物跳跃,并且空格键蓄力工夫越长跳的越高

上面开始介绍一下,咱们此次游戏的制作过程吧。

一,设计游戏的根本逻辑和界面。

这是在草稿本下面,画的一些根底的界面和事件的触发断定等等。

残缺的游戏设计并没有在外面齐全展现。

二,游戏中的 class 设计

1,player 类

在 Player 类中,咱们给了根底的本身属性:

rect 为人物呈现的初始地位,咱们将人物的初始地位搁置于随机呈现的第一个平台的两头上方,所以须要创立人物时来导入,不便绘制人物的初始地位。

faceR 属性判断人物的静止方向,1 代表向右静止,2 代表向左静止。

speed 属性为人物在 x 轴上的静止速度。

gravity 属性为人物在 y 轴上的起飞速度。

live 属性为判断人物是否存活。

Drop 函数来管制人物起飞。

Move 函数管制人物的 y 轴挪动,须要输出 time,这个 time 是玩家按住空格键的工夫,以此来管制人物 y 轴挪动的长短。

class Player():
def __init__(self, pos):
    self.rect = pos
    self.faceR = 1 #1 为向右,2 为向左
    self.speed = 2
    self.gravity = 10
    self.live = True #是否存活

def Drop(self):
    self.rect.top += self.gravity
def Move(self, time):
    tmp = 0.2*self.speed*time*time  - self.gravity
    if tmp <= 0:
        tmp = 0
    self.rect.top -= tmp
    self.rect.left += self.speed*time*self.faceR
    
    #### **2,Land 类 **

这个 class 中,咱们给了 land 类的根本属性:

image 属性是用来存储 land 的图片,

rect 属性设定了 land 的 Rect 属性,通过前面随机函数产生不同的 left 值,来管制 land 呈现的不同地位。

rect.topleft 接管外界给的 init_pos 值,即 land 的 left 值。

gravity 属性为 land 在 y 轴上的起飞速度。

Move 函数即管制 land 类的起飞。

class Land(pygame.sprite.Sprite):
def __init__(self, land_img, init_pos):
    pygame.sprite.Sprite.__init__(self)
    self.image = land_img
    self.rect = pygame.Rect(0,0,100,20)
    self.rect.topleft = init_pos
    self.gravity = 4
def Move(self):
    self.rect.top += self.gravity

三,程序的根本代码

上面是依照 pygame 的根底设置,来给定画面的宽和高,和接下来会用到的一些属性值。应该会在上面具体用到时再具体讲述。

    pygame.init()
    width = 800
    height = 800
    
    window = pygame.display.set_mode((width,height))
    pygame.display.set_caption('jumpK')
    
    pygame.font.init()
    
    time = 0
    
    white = 255, 255, 255
    black = 0, 0, 0
    
    land_frequency = 0
    
    land_width = 100
    
    #保留产生的所有 land
    lands = pygame.sprite.Group()
    
    #player = Player()
    create_player = True
    
    player_rect = pygame.Rect(0,0,30,54,) #判断人物创立
    
    jk_begin = True
    jk_space = False
    jk_left = False
    jk_right = False
    
    max_time = 0
    
    # #分数
    # score = 0
    
    clock = pygame.time.Clock()

上面的是咱们载入的一些图片和音效。

    #载入图片
    background = pygame.image.load('tmp/images/back_img.png')
    land = pygame.image.load('tmp/images/land.png')
    game_over = pygame.image.load('tmp/images/gameover.png')

    player1 = pygame.image.load('tmp/images/player_1.png')
    player2 = pygame.image.load('tmp/images/player_2.png')
    player3 = pygame.image.load('tmp/images/player_3.png')
    player4 = pygame.image.load('tmp/images/player_4.png')
    #载入游戏音效
    jump = pygame.mixer.Sound('tmp/sounds/jump.wav')
    jump.set_volume(15)
    game_over_sound = pygame.mixer.Sound('tmp/sounds/game_over.wav')
    game_over_sound.set_volume(0.05)
    pygame.mixer.music.load('tmp/sounds/background.mp3')
    pygame.mixer.music.play(-1, 0.0)
    pygame.mixer.music.set_volume(0.5)

接下来,就是须要不断更新的信息。

    running = True #游戏是否完结
    while running:

简略设置了游戏的帧率,背景什么的。

clock.tick(30)

window.blit(background, (0, 0))
pygame.draw.rect(window, white, [260, 740, 260, 50], 0)

这里是显示力度条,依据 time 来显示长度,前面咱们会对 time 进行重置。

# 显示力度条
pygame.draw.rect(window, black, [260, 740, time / 20 * 260, 50], 0)

这里通过本人设定的 land_frequency 来管制平台产生的速度。

# 产生着落的平台
if land_frequency % 50 == 0:
    land1_pos = [random.randint(0, width-land_width), 0]
    land1 = Land(land, land1_pos)
    lands.add(land1)

land_frequency += 1
if land_frequency >= 100:
    land_frequency = 0

这里应用判断来确保只运行一次代码。避免对起初的 player 产生奇怪的管制。

# 创立人物
if create_player:
    create_player = False
    player_rect.left = land1.rect.left+40
    player_rect.top = land1.rect.top-55
    player = Player(player_rect)
    #创立初始的人物
    window.blit(player1, player.rect)

咱们会在前面将每次产生的 land 存入一个 group 中,不便在这里不停的绘制,应用 land 的 Move 函数。

并在这里判断人物和 land 是否存在碰撞,并设置“jk_”结尾布尔类,这些在前面来控制程序进行。

并且当平台低于肯定高度时,咱们会将那局部 land 从 group 中消去。

for tmp_land in lands:
    #绘制着落的平台
    window.blit(land, tmp_land.rect)
    #下坠
    tmp_land.Move()
    if pygame.sprite.collide_circle(tmp_land,player):
        #score += 100
        jk_right = False
        jk_left = False
        jk_space = False
        jk_begin = True
        player.gravity = 4

    #删除底部的平台
    if tmp_land.rect.y >= 650:
        lands.remove(tmp_land)

在 player 的 live 属性为 True 时,咱们承受键盘的值,

如果是空格的话,扭转 player 的相干属性。

time 加 0.5,绘制力度条,

当 time 达到 20 时,time 将不会减少。

如果同时有左键或右键输出,咱们将扭转 player 的 faceR 属性,来管制人物的 x 轴静止方向。

# 人物空格挪动
if player.live:
    if jk_begin:
        key_pressed = pygame.key.get_pressed()
        if key_pressed[pygame.K_SPACE]:
            jump.play()
            jk_space = True
            jk_left = False
            jk_right = False
            window.blit(player2, player.rect)
            player.faceR = 0
            player.gravity = 10
            time += 0.5
            player.Move(time)
        else:
            jump.stop()
            jk_begin = False
            time = 0
        if time >= 20:
            jump.stop()
            time = 20
            max_time += 1
            if max_time >= 10:
                jk_begin = False
                time = 0


if key_pressed[pygame.K_LEFT] and key_pressed[pygame.K_SPACE]:
        jk_space = False
        jk_left = True
        jk_right = False
        window.blit(player3, player.rect)
        player.faceR = -1
        player.Move(time)
if key_pressed[pygame.K_RIGHT] and key_pressed[pygame.K_SPACE]:
        jk_space = False
        jk_left = False
        jk_right = True
        window.blit(player4, player.rect)
        player.faceR = 1
        player.Move(time)

咱们须要对人物进行一些纠正,以避免人物图像超出画面的边界。

# 纠正人物超过边缘
if player.rect.y <= -54:
    player.rect.y = -54
if player.rect.x <= 0:
    player.rect.x = 0
    time = 0
    jk_begin = False
if player.rect.x >= 770:
    player.rect.x = 770

同时,当人物的 rect.y 超出了 750 就会显示游戏完结的图片。还有 player 的 live 属性为 FALSE 这样,就不会持续承受玩家的键盘指令了。

# 游戏完结
if player.rect.y >= 750:
    game_over_sound.play()
    player.live = False
    window.blit(game_over, (0, 0))

在最初咱们对立更新人物绘制和当玩家键入不同按键时,人物的不同动作(包含失常站立,下蹲,向左看,向右看)

# 更新人物, 判断人物动作
if (not jk_right) and (not jk_left) and (not jk_space):
    window.blit(player1, player.rect)
if jk_space:
    window.blit(player2, player.rect)
if jk_left:
    window.blit(player3, player.rect)
if jk_right:
    window.blit(player4, player.rect)
player.Drop()

for event in pygame.event.get():
    if event.type == pygame.QUIT:
        running = False
pygame.display.update()

四,结言

本次是咱们首次应用 pygame 来自行进行游戏开发。

这里,咱们删去了在平台上按左、右键和 A、D 键来管制人物挪动的操作,仅用左、右键和 A、D 键来管制人物挪动的形式。

同时咱们也没有制作出大量的地形来丰盛游戏的丰富性和趣味性,仅仅应用了一直起飞的平台来代替固定的地形。

还有毛病是奇怪的静止轨迹、人物能够从下穿破平台、人物会浮空(这个应该和 pygame 的断定有些关系吧)

如果还有下次的话,心愿咱们能够扭转这些缺点吧。也心愿可能尝试页游等!

退出移动版