使用Python和Pygame开发基于长沙景点的大富翁游戏

Owen
Owen
发布时间:2026-10-15 | 5人浏览过
原创

本文介绍如何使用Python和Pygame库开发一款以长沙著名景点为背景的大富翁游戏。项目包含西站、橘子洲等8个地标及对应的特殊事件机制,如GPA变动和金钱增减。文章详细讲解了环境配置、核心代码逻辑及游戏运行效果,适合Python初学者进行实战练习。

导语

提及童年经典的电脑游戏,你脑海中浮现的是什么?

最具国民度的莫过于金山打字通,紧随其后的是扫雷和红心大战,而曾经风靡一时的单机游戏代表作当属《大富翁》。

之前的文章中我们已经分享过打字游戏和扫雷的实现,今天我们将聚焦于《大富翁》游戏的开发。

接下来,让我们一同开启这段编程之旅。

作为经典的强手棋类游戏,《大富翁》系列在十余年间长盛不衰。从第2代走红,到第3代成为经典,第4代将回合制游戏推向高峰,第5代开启网络联机对战……至今,华语地区的大富翁类游戏仍难以超越该系列的高光时刻。

掷骰子、开宝箱、跳格子,构成了80后和90后的童年记忆。好友围坐,等待掷骰子买地建房,孙小美、阿土伯、金贝贝、沙隆巴斯、钱夫人、莎拉公主等角色陪伴我们度过无数欢乐时光。

闲话少说,让我们正式进入开发环节。

一、大富翁之旅

恰逢元宵佳节,不妨来长沙游玩一番?

本款《大富翁》小游戏基于长沙著名景点设计。地图上嵌入了8个长沙标志性地点,按从上往下、从左往右的顺序依次为:西站、世界之窗、五一广场、橘子洲、植物园、博物馆、岳麓书院、岳麓山。当玩家到达这些地点时,将触发相应的特殊事件。

二、特殊事件

1)触发的特殊事件如下

西站:玩家经过西站时停留休息一天,即一回合不能掷骰子,作为回报,该玩家GPA上升0.2。

世界之窗:玩家经过世界之窗时游玩一天,即一回合不能掷骰子。

五一广场:玩家经过五一广场时体验帮忙充场跑业务,金钱增加500,GPA下降1.0。

橘子洲:玩家经过橘子洲时口渴买茶颜和吃的,金钱减少100。

植物园:玩家经过植物园时买票观看演出,金钱减少200。

博物馆:玩家经过博物馆时突然想起在世界之窗掉了东西,即直接传送到世界之窗,且一个回合不能掷骰子。

岳麓山:玩家经过岳麓山时看到最美风景,身心受到鼓舞,GPA上升0.3。

2)游戏规则

作为一款大富翁游戏,“长沙之旅”保留了传统大富翁游戏的机制,即通过买地建房赚取金钱,某玩家金钱耗尽即宣布破产,游戏结束。

在此基础上,为了体现更多元素,游戏中每个角色的实力除了财产之外,还有另一个衡量标准——GPA。当某位玩家的GPA达到4.0时,游戏结束,该玩家获胜;GPA达到1.0时,游戏结束,该玩家失败。本游戏支持2~4人玩法,为玩家准备了4位可爱的游戏角色。

三、代码演示

1)环境素材

2)运行环境

环境安装:本文用到的运行环境为Python3.7、Pycharm社区版2020、Pygame游戏模块。部分自带模块直接导入,不需要额外安装。

模块安装:pip install -i https://pypi.douban.com/simple/ +模块名

3)主程序

import pygame
import sys
import time
 
from draw import Button, draw_text, draw_mapstatus, draw_player
from game import *
from player import Player
 
 
pygame.init()
 
screen_size = (1080, 680)  # 第一个是宽度,第二个是高度
role_size = (60, 60)
screen = pygame.display.set_mode(screen_size)
pygame.display.set_caption("大富翁——长沙之旅")
map_screen = pygame.image.load('image/地图.bmp')
stop_picture = pygame.image.load('image/禁止.jpg')
stop_picture = pygame.transform.scale(stop_picture, (20, 20))
 
lose_sound = pygame.mixer.Sound('sound/失败.wav')  # 载入音效
win_sound = pygame.mixer.Sound('sound/胜利.wav')
up_sound = pygame.mixer.Sound('sound/升级.wav')
click_sound = pygame.mixer.Sound('sound/按键.wav')
chances_sound = pygame.mixer.Sound('sound/事件.wav')
 
picture_dice = []
for i in range(6):
    picture_dice.append(pygame.image.load('image/dice/%d.jpg'%(i+1)))
 
map_screen = pygame.transform.scale(map_screen, screen_size)
 
screen.blit(map_screen, (0, 0))
 
play_button = Button(screen, '开始游戏')  # 绘制开始游戏按钮
play_button.draw_button()
 
status = 0  # 控制游戏进程 0:游戏未开始 1:选择游戏人数 2:掷骰子 3:玩家行走 4:触发事件 5:买地建房 6:游戏结束
cur_player = 0  # 当前玩家
dice_answer = 1 # 掷骰子结果
player = []
role = []
 
local_init = [0, 20, 12, 32]  # 四位玩家最初的位置
map_status = []
for i in range(8):
    map_status.append(Map(i))  # 存储地产信息,包括所有者、价值、租金等
 
while True:
    if status == 0:  # 游戏未开始
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                (mouse_x, mouse_y) = event.pos
                #print(mouse_x, mouse_y)
                if click_button(mouse_x, mouse_y, 0):
                    click_sound.play()
                    num_player_button = Button(screen, '请输入游戏人数(2~4)')
                    num_player_button.draw_button()
                    draw_text(screen, (540, 440), '操作指南:按↑掷骰子、购买地产',
                              50, 'STXINGKA.TTF', pygame.Color('gold'))
                    status = 1
        pygame.display.update()
    elif status == 1:  # 选择游戏人数
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if 258 <= event.key <= 260 or 50 <= event.key <= 52: #载入相应数量的角色
                    click_sound.play()
                    role.append(pygame.image.load('image/role/小e.jpg'))
                    role.append(pygame.image.load('image/role/皮卡丘.jpg'))
                    if event.key == 259 or event.key == 51:
                        role.append(pygame.image.load('image/role/可达鸭.jpg'))
                    elif event.key == 260 or event.key == 52:
                        role.append(pygame.image.load('image/role/可达鸭.jpg'))
                        role.append(pygame.image.load('image/role/小黄鸡.jpg'))
                    screen.blit(map_screen, (0, 0))
                    for i in range(len(role)): #初始化游戏玩家
                        role[i] = pygame.transform.scale(role[i], role_size)
                        player.append(Player(i))
                        player[i].local = local_init[i]
                    draw_player(screen, player, role, stop_picture)
                    status = 2
    elif status == 2: #掷骰子
        for i in range(6):  # 绘制骰子动画
            screen.blit(picture_dice[i], (500, 400))
            pygame.display.update()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == 273:
                    dice_answer = get_dice()
                    status = 3
        pygame.display.update()
    elif status == 3: #玩家行走
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        for i in range(dice_answer):
            screen.blit(map_screen, (0, 0))
            screen.blit(picture_dice[dice_answer - 1], (500, 400))
            player[cur_player].local = (player[cur_player].local + 1) % 40
            draw_mapstatus(screen, player, map_status)
            draw_player(screen, player, role, stop_picture)
            click_sound.play()
            pygame.display.update()
            time.sleep(0.5)
        if Special(player[cur_player].local): #判断是否触发特殊事件
            status = 4
        else:  # 普通地段,判断需要买地或交租金
            local = player[cur_player].local
            if map_status[local2order(local)].owner == -1:
                chances_sound.play()
                draw_text(screen, (800, 340), '是否买下这块地?(¥%d)' % map_status[local2order(local)].value1, 30,
                          'STXINGKA.TTF', pygame.Color('grey'))
                status = 5
            elif map_status[local2order(local)].owner == cur_player and map_status[local2order(local)].level == 1:
                chances_sound.play()
                draw_text(screen, (800, 340), '是否要加盖建筑?(¥%d)' % map_status[local2order(local)].value2, 30,
                          'STXINGKA.TTF', pygame.Color('grey'))
                status = 5
            elif map_status[local2order(local)].owner == cur_player and map_status[local2order(local)].level == 2:
                cur_player = (cur_player + 1) % len(player)  # 下一个玩家掷骰子
                while player[cur_player].stop == 1:
                    player[cur_player].stop = 0
                    cur_player = (cur_player + 1) % len(player)
                status = 2
            else:
                if map_status[local2order(local)].level == 1:
                    player[cur_player].money -= map_status[local2order(local)].rent1
                    player[map_status[local2order(local)].owner].money += map_status[local2order(local)].rent1
                    screen.blit(map_screen, (0, 0))
                    screen.blit(picture_dice[dice_answer - 1], (500, 400))
                    draw_mapstatus(screen, player, map_status)
                    draw_player(screen, player, role, stop_picture)
                    draw_text(screen, (800, 340), '支付租金(¥%d)' % map_status[local2order(local)].rent1, 30,
                              'STXINGKA.TTF', pygame.Color('grey'))
                    chances_sound.play()
                elif map_status[local2order(local)].level == 2:
                    player[cur_player].money -= map_status[local2order(local)].rent2
                    player[map_status[local2order(local)].owner].money += map_status[local2order(local)].rent2
                    screen.blit(map_screen, (0, 0))
                    screen.blit(picture_dice[dice_answer - 1], (500, 400))
                    draw_mapstatus(screen, player, map_status)
                    draw_player(screen, player, role, stop_picture)
                    draw_text(screen, (800, 340), '支付租金(¥%d)' % map_status[local2order(local)].rent2, 30,
                              'STXINGKA.TTF', pygame.Color('grey'))
                    chances_sound.play()
                cur_player = (cur_player + 1) % len(player)  # 下一个玩家掷骰子
                while player[cur_player].stop == 1:
                    player[cur_player].stop = 0
                    cur_player = (cur_player + 1) % len(player)
                if not game_over(player) == 0:
                    if game_over(player) > 0:
                        win_sound.play()
                    else:
                        lose_sound.play()
                    status = 6
                else:
                    status = 2
            pygame.display.update()
    elif status == 4: #触发特殊事件
        if player[cur_player].local == 5: #C楼
            player[cur_player].money -= 100
            screen.blit(map_screen, (0, 0))
            screen.blit(picture_dice[dice_answer - 1], (500, 400))
            draw_mapstatus(screen, player, map_status)
            draw_player(screen, player, role, stop_picture)
            draw_text(screen, (800, 340), '去橘子洲购物,金钱-100', 30, 'STXINGKA.TTF', pygame.Color('grey'))
            chances_sound.play()
        elif player[cur_player].local == 11: #紫操
            player[cur_player].money += 100
            if full_somewhere(35, player):
                player[cur_player].gpa += 0.2
                screen.blit(map_screen, (0, 0))
                screen.blit(picture_dice[dice_answer - 1], (500, 400))
                draw_mapstatus(screen, player, map_status)
                draw_player(screen, player, role, stop_picture)
                draw_text(screen, (800, 340), '西站,绩点+0.2', 30, 'STXINGKA.TTF', pygame.Color('grey'))
                chances_sound.play()
            else:
                player[cur_player].local = 35
                player[cur_player].stop = 1
                screen.blit(map_screen, (0, 0))
                screen.blit(picture_dice[dice_answer - 1], (500, 400))
                draw_mapstatus(screen, player, map_status)
                draw_player(screen, player, role, stop_picture)
                draw_text(screen, (800, 340), '博物馆', 30, 'STXINGKA.TTF', pygame.Color('grey'))
                chances_sound.play()
        elif player[cur_player].local == 15: #罗姆楼
            if cur_player == 0:
                player[0].stop = 1
                player[0].gpa += 0.2
                screen.blit(map_screen, (0, 0))
                screen.blit(picture_dice[dice_answer - 1], (500, 400))
                draw_mapstatus(screen, player, map_status)
                draw_player(screen, player, role, stop_picture)
                draw_text(screen, (750, 340), '学习一天,绩点+0.2', 30, 'STXINGKA.TTF', pygame.Color('grey'))
                chances_sound.play()
        elif player[cur_player].local == 19: #主楼
            player[cur_player].gpa += 0.3
            screen.blit(map_screen, (0, 0))
            screen.blit(picture_dice[dice_answer - 1], (500, 400))
            draw_mapstatus(screen, player, map_status)
            draw_player(screen, player, role, stop_picture)
            draw_text(screen, (750, 340), '观看岳麓山风景,绩点+0.3', 30, 'STXINGKA.TTF', pygame.Color('grey'))
            chances_sound.play()
        elif player[cur_player].local == 25: #新清
            player[cur_player].money -= 200
            screen.blit(map_screen, (0, 0))
            screen.blit(picture_dice[dice_answer - 1], (500, 400))
            draw_mapstatus(screen, player, map_status)
            draw_player(screen, player, role, stop_picture)
            draw_text(screen, (800, 340), '去植物园看演出,金钱-200', 30, 'STXINGKA.TTF', pygame.Color('grey'))
            chances_sound.play()
        elif player[cur_player].local == 31: #二校门
            player[cur_player].money += 500
            player[cur_player].gpa -= 1.0
            screen.blit(map_screen, (0, 0))
            screen.blit(picture_dice[dice_answer - 1], (500, 400))
            draw_mapstatus(screen, player, map_status)
            draw_player(screen, player, role, stop_picture)
            draw_text(screen, (750, 340), '五一广场业务,金钱+500,绩点-1.0', 30, 'STXINGKA.TTF', pygame.Color('grey'))
            chances_sound.play()
        elif player[cur_player].local == 35: #校医院
            player[cur_player].stop = 1
            screen.blit(map_screen, (0, 0))
            screen.blit(picture_dice[dice_answer - 1], (500, 400))
            draw_mapstatus(screen, player, map_status)
            draw_player(screen, player, role, stop_picture)
            draw_text(screen, (800, 340), '世界之窗', 30, 'STXINGKA.TTF', pygame.Color('grey'))
            chances_sound.play()
        elif player[cur_player].local == 39: #图书馆
            if not cur_player == 2:
                player[cur_player].stop = 1
                player[cur_player].gpa += 0.2
                screen.blit(map_screen, (0, 0))
                screen.blit(picture_dice[dice_answer - 1], (500, 400))
                draw_mapstatus(screen, player, map_status)
                draw_player(screen, player, role, stop_picture)
                draw_text(screen, (800, 340), '泡在西站一天,绩点+0.2', 30, 'STXINGKA.TTF', pygame.Color('grey'))
                chances_sound.play()
        cur_player = (cur_player + 1) % len(player) #下一个玩家掷骰子
        while player[cur_player].stop == 1:
            player[cur_player].stop = 0
            cur_player = (cur_player + 1) % len(player)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        pygame.display.update()
        if not game_over(player) == 0:
            if game_over(player) > 0:
                win_sound.play()
            else:
                lose_sound.play()
            status = 6
        else:
            status = 2
    elif status == 5: #买地建房
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == 273:
                    if map_status[local2order(player[cur_player].local)].level == 0:
                        player[cur_player].money -= map_status[local2order(player[cur_player].local)].value1
                        map_status[local2order(player[cur_player].local)].owner = cur_player
                        map_status[local2order(player[cur_player].local)].level = 1
                    elif map_status[local2order(player[cur_player].local)].level == 1:
                        player[cur_player].money -= map_status[local2order(player[cur_player].local)].value2
                        map_status[local2order(player[cur_player].local)].level = 2
                cur_player = (cur_player + 1) % len(player)  # 下一个玩家掷骰子
                while player[cur_player].stop == 1:
                    player[cur_player].stop = 0
                    cur_player = (cur_player + 1) % len(player)
                status = 2
                screen.blit(map_screen, (0, 0))
                screen.blit(picture_dice[dice_answer - 1], (500, 400))
                draw_player(screen, player, role, stop_picture)
                draw_mapstatus(screen, player, map_status)
                up_sound.play()
                if not game_over(player) == 0:
                    if game_over(player) > 0:
                        win_sound.play()
                    else:
                        lose_sound.play()
                    status = 6
        pygame.display.update()
    elif status == 6:  # 游戏结束
        if game_over(player) > 0:
            draw_text(screen, (540, 340), '游戏结束,%s胜利' % player[game_over(player)-1].name,
                      50, 'STXINGKA.TTF', pygame.Color('darkgreen'))
            draw_text(screen, (540, 440), '再来一局',
                      50, 'STXINGKA.TTF', pygame.Color('darkgreen'))
 
        else :
            draw_text(screen, (540, 340), '游戏结束,%s失败' % player[- game_over(player) - 1].name,
                      50, 'STXINGKA.TTF', pygame.Color('darkgreen'))
            draw_text(screen, (540, 440), '再来一局',
                      50, 'STXINGKA.TTF', pygame.Color('darkgreen'))
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                (mouse_x, mouse_y) = event.pos
                if click_button(mouse_x, mouse_y, 1):
                    player = []
                    role = []
                    map_status = []
                    for i in range(8):
                        map_status.append(Map(i))
                    cur_player = 0
                    click_sound.play()
                    screen.blit(map_screen, (0, 0))
                    num_player_button = Button(screen, '请输入游戏人数(2~4)')
                    num_player_button.draw_button()
                    draw_text(screen, (540, 440), '操作指南:按↑掷骰子、购买地产',
                              50, 'STXINGKA.TTF', pygame.Color('gold'))
                    status = 1
        pygame.display.update()

4)玩家角色

class Player:  # 玩家类
    def __init__(self, order):
        self.money = 3000
        self.gpa = 3.0
        self.local = 0
        self.stop = 0
        if order == 0:
            self.name = '小E'
        elif order == 1:
            self.name = '皮卡丘'
        elif order == 2:
            self.name = '可达鸭'
        elif order == 3:
            self.name = '小黄鸡'

四、效果展示

1)初始界面

鼠标左键点击“开始游戏”即可!

2)选择游戏人数界面

键盘输入2~4的数字即可!

3)后续

按键盘“↑”键掷骰子、按键盘“↑”键买地(升级地产操作相同)、鼠标左键点击“再来一局”重新开始游戏!

以上就是Python+Pygame制作"长沙版"大富翁的详细内容,更多关于Python Pygame大富翁的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表