用Python製作小游戲,上班摸魚能玩一天【內附源碼】

来源:https://www.cnblogs.com/tuixiulaozhou/archive/2022/10/07/16759672.html
-Advertisement-
Play Games

1、24點小游戲 源碼分享: import os import sys import pygame from cfg import * from modules import * from fractions import Fraction '''檢查控制項是否被點擊''' def checkClic ...


1、24點小游戲

 

 

源碼分享:

 
import os
import sys
import pygame
from cfg import *
from modules import *
from fractions import Fraction
 
 
'''檢查控制項是否被點擊'''
def checkClicked(group, mouse_pos, group_type='NUMBER'):
    selected = []
    # 數字卡片/運算符卡片
    if group_type == GROUPTYPES[0] or group_type == GROUPTYPES[1]:
        max_selected = 2 if group_type == GROUPTYPES[0] else 1
        num_selected = 0
        for each in group:
            num_selected += int(each.is_selected)
        for each in group:
            if each.rect.collidepoint(mouse_pos):
                if each.is_selected:
                    each.is_selected = not each.is_selected
                    num_selected -= 1
                    each.select_order = None
                else:
                    if num_selected < max_selected:
                        each.is_selected = not each.is_selected
                        num_selected += 1
                        each.select_order = str(num_selected)
            if each.is_selected:
                selected.append(each.attribute)
    # 按鈕卡片
    elif group_type == GROUPTYPES[2]:
        for each in group:
            if each.rect.collidepoint(mouse_pos):
                each.is_selected = True
                selected.append(each.attribute)
    # 拋出異常
    else:
        raise ValueError('checkClicked.group_type unsupport %s, expect %s, %s or %s...' % (group_type, *GROUPTYPES))
    return selected
 
 
'''獲取數字精靈組'''
def getNumberSpritesGroup(numbers):
    number_sprites_group = pygame.sprite.Group()
    for idx, number in enumerate(numbers):
        args = (*NUMBERCARD_POSITIONS[idx], str(number), NUMBERFONT, NUMBERFONT_COLORS, NUMBERCARD_COLORS, str(number))
        number_sprites_group.add(Card(*args))
    return number_sprites_group
 
 
'''獲取運算符精靈組'''
def getOperatorSpritesGroup(operators):
    operator_sprites_group = pygame.sprite.Group()
    for idx, operator in enumerate(operators):
        args = (*OPERATORCARD_POSITIONS[idx], str(operator), OPERATORFONT, OPREATORFONT_COLORS, OPERATORCARD_COLORS, str(operator))
        operator_sprites_group.add(Card(*args))
    return operator_sprites_group
 
 
'''獲取按鈕精靈組'''
def getButtonSpritesGroup(buttons):
    button_sprites_group = pygame.sprite.Group()
    for idx, button in enumerate(buttons):
        args = (*BUTTONCARD_POSITIONS[idx], str(button), BUTTONFONT, BUTTONFONT_COLORS, BUTTONCARD_COLORS, str(button))
        button_sprites_group.add(Button(*args))
    return button_sprites_group
 
 
'''計算'''
def calculate(number1, number2, operator):
    operator_map = {'+': '+', '-': '-', '×': '*', '÷': '/'}
    try:
        result = str(eval(number1+operator_map[operator]+number2))
        return result if '.' not in result else str(Fraction(number1+operator_map[operator]+number2))
    except:
        return None
 
 
'''在屏幕上顯示信息'''
def showInfo(text, screen):
    rect = pygame.Rect(200, 180, 400, 200)
    pygame.draw.rect(screen, PAPAYAWHIP, rect)
    font = pygame.font.Font(FONTPATH, 40)
    text_render = font.render(text, True, BLACK)
    font_size = font.size(text)
    screen.blit(text_render, (rect.x+(rect.width-font_size[0])/2, rect.y+(rect.height-font_size[1])/2))
 
 
'''主函數'''
def main():
    # 初始化, 導入必要的游戲素材
    pygame.init()
    pygame.mixer.init()
    screen = pygame.display.set_mode(SCREENSIZE)
    pygame.display.set_caption('24 point —— 九歌')
    win_sound = pygame.mixer.Sound(AUDIOWINPATH)
    lose_sound = pygame.mixer.Sound(AUDIOLOSEPATH)
    warn_sound = pygame.mixer.Sound(AUDIOWARNPATH)
    pygame.mixer.music.load(BGMPATH)
    pygame.mixer.music.play(-1, 0.0)
    # 24點游戲生成器
    game24_gen = game24Generator()
    game24_gen.generate()
    # 精靈組
    # --數字
    number_sprites_group = getNumberSpritesGroup(game24_gen.numbers_now)
    # --運算符
    operator_sprites_group = getOperatorSpritesGroup(OPREATORS)
    # --按鈕
    button_sprites_group = getButtonSpritesGroup(BUTTONS)
    # 游戲主迴圈
    clock = pygame.time.Clock()
    selected_numbers = []
    selected_operators = []
    selected_buttons = []
    is_win = False
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit(-1)
            elif event.type == pygame.MOUSEBUTTONUP:
                mouse_pos = pygame.mouse.get_pos()
                selected_numbers = checkClicked(number_sprites_group, mouse_pos, 'NUMBER')
                selected_operators = checkClicked(operator_sprites_group, mouse_pos, 'OPREATOR')
                selected_buttons = checkClicked(button_sprites_group, mouse_pos, 'BUTTON')
        screen.fill(AZURE)
        # 更新數字
        if len(selected_numbers) == 2 and len(selected_operators) == 1:
            noselected_numbers = []
            for each in number_sprites_group:
                if each.is_selected:
                    if each.select_order == '1':
                        selected_number1 = each.attribute
                    elif each.select_order == '2':
                        selected_number2 = each.attribute
                    else:
                        raise ValueError('Unknow select_order %s, expect 1 or 2...' % each.select_order)
                else:
                    noselected_numbers.append(each.attribute)
                each.is_selected = False
            for each in operator_sprites_group:
                each.is_selected = False
            result = calculate(selected_number1, selected_number2, *selected_operators)
            if result is not None:
                game24_gen.numbers_now = noselected_numbers + [result]
                is_win = game24_gen.check()
                if is_win:
                    win_sound.play()
                if not is_win and len(game24_gen.numbers_now) == 1:
                    lose_sound.play()
            else:
                warn_sound.play()
            selected_numbers = []
            selected_operators = []
            number_sprites_group = getNumberSpritesGroup(game24_gen.numbers_now)
        # 精靈都畫到screen上
        for each in number_sprites_group:
            each.draw(screen, pygame.mouse.get_pos())
        for each in operator_sprites_group:
            each.draw(screen, pygame.mouse.get_pos())
        for each in button_sprites_group:
            if selected_buttons and selected_buttons[0] in ['RESET', 'NEXT']:
                is_win = False
            if selected_buttons and each.attribute == selected_buttons[0]:
                each.is_selected = False
                number_sprites_group = each.do(game24_gen, getNumberSpritesGroup, number_sprites_group, button_sprites_group)
                selected_buttons = []
            each.draw(screen, pygame.mouse.get_pos())
        # 游戲勝利
        if is_win:
            showInfo('Congratulations', screen)
        # 游戲失敗
        if not is_win and len(game24_gen.numbers_now) == 1:
            showInfo('Game Over', screen)
        pygame.display.flip()
        clock.tick(30)
 
 
'''run'''
if __name__ == '__main__':
    main()

 

2、保衛森林

玩法詳解:類似保衛蘿蔔,塔防類的小游戲,佈局一定要合理,考慮射程屬性等等

   

 

 

3、平衡木

玩法:也是小時候的經典游戲,控制左右就行,到後面才有一點點難度。

 

 

源碼分享:

 
import cfg
from modules import breakoutClone
 
 
'''主函數'''
def main():
    game = breakoutClone(cfg)
    game.run()
 
 
'''run'''
if __name__ == '__main__':
    main()

4、外星人入侵

玩法:這讓我想起了魂鬥羅那第幾關的boss,有點類似,不過魂鬥羅那個難度肯定高點。

 

 

 

源碼分享:

 
import os
import sys
import cfg
import random
import pygame
from modules import *
 
 
'''開始游戲'''
def startGame(screen):
    clock = pygame.time.Clock()
    # 載入字體
    font = pygame.font.SysFont('arial', 18)
    if not os.path.isfile('score'):
        f = open('score', 'w')
        f.write('0')
        f.close()
    with open('score', 'r') as f:
        highest_score = int(f.read().strip())
    # 敵方
    enemies_group = pygame.sprite.Group()
    for i in range(55):
        if i < 11:
            enemy = enemySprite('small', i, cfg.WHITE, cfg.WHITE)
        elif i < 33:
            enemy = enemySprite('medium', i, cfg.WHITE, cfg.WHITE)
        else:
            enemy = enemySprite('large', i, cfg.WHITE, cfg.WHITE)
        enemy.rect.x = 85 + (i % 11) * 50
        enemy.rect.y = 120 + (i // 11) * 45
        enemies_group.add(enemy)
    boomed_enemies_group = pygame.sprite.Group()
    en_bullets_group = pygame.sprite.Group()
    ufo = ufoSprite(color=cfg.RED)
    # 我方
    myaircraft = aircraftSprite(color=cfg.GREEN, bullet_color=cfg.WHITE)
    my_bullets_group = pygame.sprite.Group()
    # 用於控制敵方位置更新
    # --移動一行
    enemy_move_count = 24
    enemy_move_interval = 24
    enemy_move_flag = False
    # --改變移動方向(改變方向的同時集體下降一次)
    enemy_change_direction_count = 0
    enemy_change_direction_interval = 60
    enemy_need_down = False
    enemy_move_right = True
    enemy_need_move_row = 6
    enemy_max_row = 5
    # 用於控制敵方發射子彈
    enemy_shot_interval = 100
    enemy_shot_count = 0
    enemy_shot_flag = False
    # 游戲進行中
    running = True
    is_win = False
    # 主迴圈
    while running:
        screen.fill(cfg.BLACK)
        for event in pygame.event.get():
            # --點右上角的X或者按Esc鍵退出游戲
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()
            # --射擊
            if event.type == pygame.MOUSEBUTTONDOWN:
                my_bullet = myaircraft.shot()
                if my_bullet:
                    my_bullets_group.add(my_bullet)
        # --我方子彈與敵方/UFO碰撞檢測
        for enemy in enemies_group:
            if pygame.sprite.spritecollide(enemy, my_bullets_group, True, None):
                boomed_enemies_group.add(enemy)
                enemies_group.remove(enemy)
                myaircraft.score += enemy.reward
        if pygame.sprite.spritecollide(ufo, my_bullets_group, True, None):
            ufo.is_dead = True
            myaircraft.score += ufo.reward
        # --更新並畫敵方
        # ----敵方子彈
        enemy_shot_count += 1
        if enemy_shot_count > enemy_shot_interval:
            enemy_shot_flag = True
            enemies_survive_list = [enemy.number for enemy in enemies_group]
            shot_number = random.choice(enemies_survive_list)
            enemy_shot_count = 0
        # ----敵方移動
        enemy_move_count += 1
        if enemy_move_count > enemy_move_interval:
            enemy_move_count = 0
            enemy_move_flag = True
            enemy_need_move_row -= 1
            if enemy_need_move_row == 0:
                enemy_need_move_row = enemy_max_row
            enemy_change_direction_count += 1
            if enemy_change_direction_count > enemy_change_direction_interval:
                enemy_change_direction_count = 1
                enemy_move_right = not enemy_move_right
                enemy_need_down = True
                # ----每次下降提高移動和射擊速度
                enemy_move_interval = max(15, enemy_move_interval-3)
                enemy_shot_interval = max(50, enemy_move_interval-10)
        # ----遍歷更新
        for enemy in enemies_group:
            if enemy_shot_flag:
                if enemy.number == shot_number:
                    en_bullet = enemy.shot()
                    en_bullets_group.add(en_bullet)
            if enemy_move_flag:
                if enemy.number in range((enemy_need_move_row-1)*11, enemy_need_move_row*11):
                    if enemy_move_right:
                        enemy.update('right', cfg.SCREENSIZE[1])
                    else:
                        enemy.update('left', cfg.SCREENSIZE[1])
            else:
                enemy.update(None, cfg.SCREENSIZE[1])
            if enemy_need_down:
                if enemy.update('down', cfg.SCREENSIZE[1]):
                    running = False
                    is_win = False
                enemy.change_count -= 1
            enemy.draw(screen)
        enemy_move_flag = False
        enemy_need_down = False
        enemy_shot_flag = False
        # ----敵方爆炸特效
        for boomed_enemy in boomed_enemies_group:
            if boomed_enemy.boom(screen):
                boomed_enemies_group.remove(boomed_enemy)
                del boomed_enemy
        # --敵方子彈與我方飛船碰撞檢測
        if not myaircraft.one_dead:
            if pygame.sprite.spritecollide(myaircraft, en_bullets_group, True, None):
                myaircraft.one_dead = True
        if myaircraft.one_dead:
            if myaircraft.boom(screen):
                myaircraft.resetBoom()
                myaircraft.num_life -= 1
                if myaircraft.num_life < 1:
                    running = False
                    is_win = False
        else:
            # ----更新飛船
            myaircraft.update(cfg.SCREENSIZE[0])
            # ----畫飛船
            myaircraft.draw(screen)
        if (not ufo.has_boomed) and (ufo.is_dead):
            if ufo.boom(screen):
                ufo.has_boomed = True
        else:
            # ----更新UFO
            ufo.update(cfg.SCREENSIZE[0])
            # ----畫UFO
            ufo.draw(screen)
        # --畫我方飛船子彈
        for bullet in my_bullets_group:
            if bullet.update():
                my_bullets_group.remove(bullet)
                del bullet
            else:
                bullet.draw(screen)
        # --畫敵方子彈
        for bullet in en_bullets_group:
            if bullet.update(cfg.SCREENSIZE[1]):
                en_bullets_group.remove(bullet)
                del bullet
            else:
                bullet.draw(screen)
        if myaircraft.score > highest_score:
            highest_score = myaircraft.score
        # --得分每增加2000我方飛船增加一條生命
        if (myaircraft.score % 2000 == 0) and (myaircraft.score > 0) and (myaircraft.score != myaircraft.old_score):
            myaircraft.old_score = myaircraft.score
            myaircraft.num_life = min(myaircraft.num_life + 1, myaircraft.max_num_life)
        # --敵人都死光了的話就勝利了
        if len(enemies_group) < 1:
            is_win = True
            running = False
        # --顯示文字
        # ----當前得分
        showText(screen, 'SCORE: ', cfg.WHITE, font, 200, 8)
        showText(screen, str(myaircraft.score), cfg.WHITE, font, 200, 24)
        # ----敵人數量
        showText(screen, 'ENEMY: ', cfg.WHITE, font, 370, 8)
        showText(screen, str(len(enemies_group)), cfg.WHITE, font, 370, 24)
        # ----歷史最高分
        showText(screen, 'HIGHEST: ', cfg.WHITE, font, 540, 8)
        showText(screen, str(highest_score), cfg.WHITE, font, 540, 24)
        # ----FPS
        showText(screen, 'FPS: ' + str(int(clock.get_fps())), cfg.RED, font, 8, 8)
        # --顯示剩餘生命值
        showLife(screen, myaircraft.num_life, cfg.GREEN)
        pygame.display.update()
        clock.tick(cfg.FPS)
    with open('score', 'w') as f:
        f.write(str(highest_score))
    return is_win
 
 
'''主函數'''
def main():
    # 初始化
    pygame.init()
    pygame.display.set_caption('外星人入侵 —— 九歌')
    screen = pygame.display.set_mode(cfg.SCREENSIZE)
    pygame.mixer.init()
    pygame.mixer.music.load(cfg.BGMPATH)
    pygame.mixer.music.set_volume(0.4)
    pygame.mixer.music.play(-1)
    while True:
        is_win = startGame(screen)
        endInterface(screen, cfg.BLACK, is_win)
  Python學習群:748989764
 
'''run'''
if __name__ == '__main__':
    main()

5、炸彈人

玩法詳解:小時候的又一經典游戲,小時候很多次都被自己炸死了。

 

 

 

6、五子棋

玩法詳解:小時候很愛玩,先出是有必勝方法的,後面才知道會有禁手這個規則,就比較複雜了,大家可以學一下先出必勝的開局,有浦月、流星、丘月、游星、慧星等等。

 

 

7、坦克大戰

玩法詳解:這是經典中的經典,我喜歡玩雙人模式,後面有一些改版的模式,這是我覺得少數幾個現在玩都不過時的游戲。

 

 

8、超級瑪麗

玩法詳解:經典中的經典,小時候玩覺得可難了,操作不必介紹了吧。

 

9、水果忍者

玩法詳解:切水果風靡一時的游戲,不知道為啥總是切刀炸掉,挺解壓的游戲。

 

 

10、推箱子

攻略大全:以前的那個手機上都有的游戲,越推到後面的關卡越難,我好像是玩到二十多關就玩不下去了。

 

11、最強游戲

游戲體驗:可太難控制了。

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • SSM · IOC ·AOP 初識Spring : Spring全家桶 Spring Framework 底層框架,設計性框架 Spring Boot 加速開發,提高開發速度 Spring Cloud 分散式開發 Spring Framework系統架構 Spring Framework是Sprin ...
  • 我的博客 在寫python腳本的時候,例如,我寫一個test1.py def test(n): print(n) if __name__ == '__main__': n = 1 test(1) 接下來打開cmd命令視窗,執行命令 python test.py 結果是把1列印出來 這時候就會有同學有 ...
  • 一、CentOS 7.9 安裝 Python-3.9.5 地址 https://www.python.org https://www.python.org/ftp/python/3.9.5 查看當前python版本 python python -V 可以看到執行python,預設是2.7.5 二、安 ...
  • 1、原因 不知不覺已經從事java開發好幾年了,成了人們口中的老司機。但是一直都是恍恍惚惚過來,對於框架底層實現一直都沒有怎麼瞭解過,只是在面試的時候背些面試題。慢慢地發現不能這樣,需要振作,笑~~~~。從這篇開始,記錄自己對於Spring載入過程的源碼查看。 ## 2、開始 1、在Spring載入 ...
  • 1. 用靜態工廠方法代替構造器 說明 在方法內部添加一個靜態方法,用於獲取一個對象,代替構造器的功能; 比如,在boolean包裝Boolean類中,就有valueOf方法可以代替構造方法獲得一個Boolean對象; public static Boolean valueOf(boolean b) ...
  • 前言 看看如何用 python 爬取知乎的公開收藏夾 內容 嘗試 第一個方法 開始的時候用 python ,request 庫進行的網頁請求,在請求你的收藏夾總界面的時候還可以返回信息,這個 url, https://www.zhihu.com/people/xxx/collections,,xxx ...
  • ## 創建leadership數據框 manager <- c(1,2,3,4,5) date <-c("10/24/08","10/28/08","10/1/08","10/12/08","5/1/09") country <- c("US","US","UK","UK","UK") gender ...
  • R 語言是為數學研究工作者設計的一種數學編程語言,主要用於統計分析、繪圖、數據挖掘。 如果你是一個電腦程式的初學者並且急切地想瞭解電腦的通用編程,R 語言不是一個很理想的選擇,可以選擇 Python、C 或 Java。 R 語言與 C 語言都是貝爾實驗室的研究成果,但兩者有不同的側重領域,R 語 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...