1. 程式人生 > >簡單 坦克大戰 pygame -製作

簡單 坦克大戰 pygame -製作

首先,第一步,遊戲簡單素材的準備。

炮彈,坦克移動。音樂-開火素材。

其次,思路整理。

我們需要幾個類,分別是玩家類,敵人類,炮彈類及地圖類,開始遊戲介面以及結束介面,血條等等。

開始coding。

主函式,new一個物件(java亂入emmm),宣告一個物件。

# encoding : utf-8
# anthor : comi
from gameloop import *
from pygame import *
import pygame,sys,time

if __name__ == '__main__':
    player = game()    # 宣告一個類物件
    player.game_start('KEEP-GOING')    # 呼叫開始函式
    while player.playing:    # 進入遊戲執行
        player.new()    # 開始遊戲
    player.screen.fill(black)
    player.game_start('GAME-OVER')    # 遊戲結束
    time.sleep(1.5)    # 可以不要

這裡可以根據自己的需要進行更改相關程式碼

接下來 遊戲的主迴圈

# encoding : utf-8
# author : comi
from setting import *
from pygame import *
from Sprite import *
import pygame,sys
vec = pygame.math.Vector2


class game:    # 遊戲類 包含迴圈等
    def __init__(self):    # 初始化
        pygame.init()    # pygame 初始化
        pygame.display.set_caption("Keep-Going")    # 遊戲視窗 左上角名稱
        self.screen = pygame.display.set_mode((width, height))    # 遊戲視窗的大小
        self.FpsClock = pygame.time.Clock()    # 設定遊戲的重新整理率
        self.playing = True    # 進入遊戲的狀態
        self.running = True    # 遊戲執行的狀態
        self.Waiting = True    # 遊戲等待的狀態
        self.Pblood = 100    # 玩家血量
        self.Eblood = 100    # 敵人血量
        self.player = Player()    # 宣告一個遊戲玩家物件
        self.enemy = Enemy()    # 宣告一個敵人物件
        self.all_groups = pygame.sprite.Group()    #    通過pygame自帶的 group 來判斷碰撞檢測
        self.player_groups = pygame.sprite.Group()
        self.Map_groups = pygame.sprite.Group()
        self.Enemy_groups = pygame.sprite.Group()

    def new(self):    # 開始一個遊戲
        self.player_groups.add(self.player)    # 將玩家新增到玩家組
        self.all_groups.add(self.player)    # 將玩家新增到 所有組

        self.Enemy_groups.add(self.enemy)
        self.all_groups.add(self.enemy)

        for platfroms in Map1:    # 地圖
            p = Platform(*platfroms)     # 取出所有值
            self.Map_groups.add(p)
            self.all_groups.add(p)

        self.run()    # 呼叫函式運行遊戲

    def game_start(self,text):     # 遊戲的開始介面
        self.text_draw(width / 2, height / 4, 64, text)  # 文字
        self.text_draw(width / 2, height * 3 / 4, 25,'Press any key to continue',)  # 文字
        pygame.display.update()    # 更行展示
        while self.Waiting:    # 實現 按鍵等待開始效果
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == pygame.KEYDOWN:    
                    self.Waiting = False

    def update(self):    # 畫面更新
        self.Map_groups.update()    
        self.player_groups.update()
        self.enemy.Bullet_groups.update(self.enemy.flag)    # 通過按鍵判斷子彈方向
        self.player.Bullet_groups.update(self.player.flag)
        self.Enemy_groups.update()

        hit = pygame.sprite.groupcollide(self.player.Bullet_groups, self.Map_groups, True,False)   # 子彈碰牆消失
        hit = pygame.sprite.groupcollide(self.enemy.Bullet_groups, self.Map_groups, True, False)

        PMC = pygame.sprite.spritecollide(self.player,self.Map_groups,False,False)      # 撞牆
        if PMC:
            key_pressed = pygame.key.get_pressed()
            if key_pressed[pygame.K_a]:
                self.player.pos.x = self.player.pos.x + gap
            if key_pressed[pygame.K_d]:
                self.player.pos.x = self.player.pos.x - gap
            if key_pressed[pygame.K_w]:
                self.player.pos.y = self.player.pos.y + gap
            if key_pressed[pygame.K_s]:
                self.player.pos.y = self.player.pos.y - gap

        EMC = pygame.sprite.spritecollide(self.enemy,self.Map_groups,False,False)       # 撞牆
        if EMC:
            key_pressed = pygame.key.get_pressed()
            if key_pressed[pygame.K_LEFT]:
                self.enemy.pos.x = self.enemy.pos.x + gap
            if key_pressed[pygame.K_RIGHT]:
                self.enemy.pos.x = self.enemy.pos.x - gap
            if key_pressed[pygame.K_UP]:
                self.enemy.pos.y = self.enemy.pos.y + gap
            if key_pressed[pygame.K_DOWN]:
                self.enemy.pos.y = self.enemy.pos.y - gap

    def run(self):    
        while self.running:
            self.FpsClock.tick(Fps)    # 設定幀率
            self.events()    # 獲取事件
            self.draw_pic()    # 畫出圖片
            self.update()    

            f self.Eblood <= 0: # enemy    
                self.screen.fill(black)
                self.game_start('P1 WIN!')
                time.sleep(1.5)
                self.running = False
                self.playing = False

            if self.Pblood <= 0: # Player
                self.screen.fill(black)
                self.game_start('P2 WIN!')
                time.sleep(1.5)
                self.running = False
                self.playing = False

    def text_draw(self, x, y, size, text):    # 文字展示函式
        self.font = pygame.font.Font('freesansbold.ttf', size)    # 字型,大小
        self.text_surf = self.font.render(text, True, red)    # 顏色
        self.text_rect = self.text_surf.get_rect()    # 矩形
        self.text_rect.center = (x, y)    # 位置
        self.screen.blit(self.text_surf, self.text_rect)    # 覆蓋展示

    def draw_pic(self):    
        self.screen.fill(white)    # 背景
        self.text_draw(900,50,30,"KEEP")    # 文字
        self.text_draw(900, 100, 30, "GOING")

        self.text_draw(820, 150, 20, "P1:")
        self.text_draw(820, 200, 20, "P2:")
        
        self.text_draw(900, 250, 20, "Attention!")
        self.text_draw(900,300,20,"The Bullet Can")
        self.text_draw(900, 350, 20, "Be Control!")
        self.bar_draw(850, 145, self.Pblood)    # 血條
        hit = pygame.sprite.groupcollide(self.enemy.Bullet_groups, self.player_groups, True, False)    # 血條減少
        if hit:
            self.Pblood = self.Pblood - randint(10, 15)
            self.bar_draw(850, 145, self.Pblood)

        self.bar_draw(850, 195, self.Eblood)
        hit = pygame.sprite.groupcollide(self.player.Bullet_groups, self.Enemy_groups, True, False)
        if hit:
            self.Eblood = self.Eblood - randint(10, 15)
            self.bar_draw(850, 195, self.Eblood)

        self.Map_groups.draw(self.screen)    # 畫出圖片
        self.player_groups.draw(self.screen)
        self.Enemy_groups.draw(self.screen)
        self.player.Bullet_groups.draw(self.screen)
        self.enemy.Bullet_groups.draw(self.screen)

        pygame.display.update()    

    def bar_draw(self, x, y, pct):    # 血條函式
        #  draw a bar    
        if pct <= 0:
            pct = 0
        Bar_Lenth = 100
        Bar_Height = 10
        Fill_Lenth = (pct / 100) * Bar_Lenth
        Out_rect = pygame.Rect(x, y, Bar_Lenth, Bar_Height)
        Fill_rect = pygame.Rect(x, y, Fill_Lenth, Bar_Height)
        pygame.draw.rect(self.screen, green, Fill_rect)
        pygame.draw.rect(self.screen, red, Out_rect, 2)

    def events(self):    # 事件
        for events in pygame.event.get():
            if events.type == pygame.QUIT:
                self.running = False
                self.playing = False






在主迴圈內實現了很多功能,文字視窗展示,血條展示,以及整個遊戲迴圈的定義都是可以拿來借鑑的,我也是從油管主上學來的。

接下來,精靈類,包含玩家,敵人。子彈,地圖四部分。

# encoding : utf-8
# antuor : comi
from setting import *
from pygame import *
import pygame,sys,time
from random import *
from math import *

vec = pygame.math.Vector2    # 運用向量

class Player(pygame.sprite.Sprite):    # 玩家類
    Bullet_groups = pygame.sprite.Group()
    flag = 1    # 判斷方向的flag
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\KeepGoing\img\down.png').convert()    # 圖片的載入
        self.image.set_colorkey(white)    # 設定忽略白色
        self.rect = self.image.get_rect()
        self.rect.midbottom = (115, 130)    

        self.pos = vec(115, 130)

        self.last_time = time.time()    #記錄上一次時間 用來設定子彈頻率等

    def update(self):    
        key_pressed = pygame.key.get_pressed()    # 按鍵獲取
        if key_pressed[pygame.K_a]:
            self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\KeepGoing\img\left.png').convert()
            self.image.set_colorkey(white)
            self.pos.x -= move_space    # 位置移動
            self.flag = 2
        if key_pressed[pygame.K_d]:
            self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\KeepGoing\img\right.png').convert()
            self.image.set_colorkey(white)
            self.pos.x += move_space
            self.flag = 1
        if key_pressed[pygame.K_w]:
            self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\KeepGoing\img\up.png').convert()
            self.image.set_colorkey(white)
            self.pos.y -= move_space
            self.flag = 3
        if key_pressed[pygame.K_s]:
            self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\KeepGoing\img\down.png').convert()
            self.image.set_colorkey(white)
            self.pos.y += move_space
            self.flag = 4
        if key_pressed[pygame.K_SPACE]:
            self.shoot()
        self.rect.midbottom = self.pos    

    def shoot(self):    # 開火
        self.now = time.time()    # 獲取現在時間
        if self.now - self.last_time > 0.8:    # 子彈時間間隔
          # 這裡顯示錯誤了,應該在if 語句內 包含以下部分
     pygame.mixer.music.load(r'C:\Users\Administrator\Desktop\KeepGoing\sounds\expl.wav') 
            pygame.mixer.music.play()    # 音樂載入
            bullet = Bullet(self.pos.x, self.pos.y)
            self.Bullet_groups.add(bullet)    
            self.last_time = self.now


class Platform(pygame.sprite.Sprite):    # 地圖建立
    def __init__(self, x, y, w, h):    # x,y,寬,高
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((w, h)) # 磚塊大小
        self.image.fill(yellow)    # 磚顏色
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y


class Enemy(pygame.sprite.Sprite):    # 與player 相同
    Bullet_groups = pygame.sprite.Group()
    flag = 1
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\KeepGoing\img\down.png').convert()
        self.image.set_colorkey(white)
        self.rect = self.image.get_rect()
        self.rect.midbottom = (315, 130)
        self.pos = vec(315, 130)
        self.bar = 100
        self.last_time = time.time()
        self.flag = 1

    def update(self):
        key_pressed = pygame.key.get_pressed()
        if key_pressed[pygame.K_LEFT]:
            self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\KeepGoing\img\left.png').convert()
            self.image.set_colorkey(white)
            self.pos.x -= move_space
            self.flag = 2
        if key_pressed[pygame.K_RIGHT]:
            self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\KeepGoing\img\right.png').convert()
            self.image.set_colorkey(white)
            self.pos.x += move_space
            self.flag = 1
        if key_pressed[pygame.K_UP]:
            self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\KeepGoing\img\up.png').convert()
            self.image.set_colorkey(white)
            self.pos.y -= move_space
            self.flag = 3
        if key_pressed[pygame.K_DOWN]:
            self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\KeepGoing\img\down.png').convert()
            self.image.set_colorkey(white)
            self.pos.y += move_space
            self.flag = 4
        if key_pressed[pygame.K_p]:
            self.shoot()

        self.rect.midbottom = self.pos

    def shoot(self):
        self.now = time.time()
        if self.now - self.last_time > 0.8:
            pygame.mixer.music.load(r'C:\Users\Administrator\Desktop\KeepGoing\sounds\expl.wav')
            pygame.mixer.music.play()
            bullet = Bullet(self.pos.x, self.pos.y)
            self.Bullet_groups.add(bullet)
            self.Bullet_groups.update(self.flag)
            self.last_time = self.now


class Bullet(pygame.sprite.Sprite):    # 炮彈組
    def __init__(self, x, y):    # 炮彈該有的位置 玩家周圍
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\KeepGoing\img\dot.png ').convert()
        self.image.set_colorkey(white)
        self.rect = self.image.get_rect()
        self.rect.centerx = x + 10    # 這裡是準確的位置,未進行準確更改
        self.rect.bottom = y - 12
        self.speed = 5

    def update(self,flag):    
        if flag == 1:   # right
            self.rect.x += self.speed
        if flag == 2:   # left
            self.rect.x -= self.speed
        if flag == 3:   #up
            self.rect.y -= self.speed
        if flag == 4:   # down
            self.rect.y += self.speed

最後,便是相關的設定檔案了


# encoding : utf-8
# author :comi
width = 1000
height = 600
Fps = 60
food = 20
gap = 3
move_space = 1.5
back_space = 5
Map1 = [(0, 0, width*2, 10), (0, 10, 10, height * 2),
        (0, height-10, width * 2, 10), (width - 210, 0, 10, height * 2),
        (50,50,100,20),(250,50,100,20),(150,230,100,20),(100,340,200,20),
        (50, 70, 20, 90), (130, 70, 20, 90),(250,70,20,90),(330,70,20,90),
        (130,280,20,70),(250,300,20,50),
        (80,320,20,20),(300,320,20,20),(185,200,30,30),(185,250,30,30),
        (60,300,20,20),(320,300,20,20),
        (40,280,20,20),(340,280,20,20),
        (490,100,160,40),(650,100,40,200),(425,250,150,40),(425,290,40,80),
        (510,365,160,40),(695,460,95,40),(595,454,40,100),(190,460,30,30),
        (300,450,200,40),(100,425,30,130),(200,520,230,25),(725,70,30,30),
        (725,140,30,30),(725,210,30,30),(725,280,30,30),(725,365,30,30)
        ]    # map
# color

black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
green = (0, 255,0)
blue = (0, 0, 255)
yellow = ( 255,200,0)
purple = (128,138,135)

這個坦克大戰還有一些小的bug,比如說,當你按下SPACE 開火是,第一發炮彈已經出去了,當你按下相反方向,子彈會按你第二次按下的方向移動。(不打算解決,開始學習遊戲ai,和橫板遊戲的製作)

有想法的同學可以和我交流,歡迎大家留言。

最後,執行效果如下 ,雙人操作 p1:w a s d space 開火 p2: 上 下左 右  p 開火

相關推薦

簡單 坦克大戰 pygame -製作

首先,第一步,遊戲簡單素材的準備。 炮彈,坦克移動。音樂-開火素材。 其次,思路整理。 我們需要幾個類,分別是玩家類,敵人類,炮彈類及地圖類,開始遊戲介面以及結束介面,血條等等。 開始coding。 主函式,new一個物件(java亂入emmm),宣告一個物件。

c++版(簡單)坦克大戰

c++實現了A *自動尋路 自動編輯地圖 雙人模式思路是 一個單獨的導演類(控制器)控制所有類 其它類都繼承一個純虛函數。ide vs2017源碼地址 https://download.csdn.net/download/sinat_35360663/10278997c++版(簡單)坦克大戰

C#面向物件簡單坦克大戰(創意)

TankDemo 介紹 一個c#簡單桌面應用(遊戲)。 基本上實現了坦克大戰的相應功能。 參考最下方的截圖 特點 支援使用者登入註冊,儲存成績,成績排名。(然並….) 關卡無限

c語言簡單坦克大戰(AllenEnemyTrank文件)

user hang 設置 pri efault struct home 大戰 ntc AllenEnemyTrank.h typedef struct ENEMYTRANK { int x, y;//我的坦克中心坐標 int m, n;//我的坦克子彈的坐

c語言簡單坦克大戰(AllenUserTrank文件)

++ 中心 pre tchar windows.h getc print window edi AllenUserTrank.h typedef struct USERTRANK2 { int x, y;//我的坦克中心坐標 int m, n;//我的坦克

canvas--製作坦克大戰(demo)

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style&

HTML5製作坦克大戰遊戲+Canvas繪製基礎圖形——學習筆記一

1.離線儲存:1)儲存到本地,可以離線瀏覽網頁  2)不用cookie(安全性不太高,來回互動的資料量比較大) 2.語音識別 3.影象識別 4.HTML5遊戲 5.CSS3的強大之處:動畫和各種選擇

HTML5+JavaScript製作坦克大戰遊戲——學習筆記三

1.接《HTML5+JavaScript製作坦克大戰遊戲——學習筆記二》 解決了以下問題: 1)可以同時傳送多顆子彈 2)在第一顆子彈消亡之前傳送第二顆子彈,第一顆子彈不會消失 示例程式碼:(TankBattle.html) <!DOCTYPE html> &

HTML5 坦克大戰遊戲的製作思路

程式碼 DEMO 不管寫的過程中覺得有多便祕,寫完了回過頭再去看這個遊戲其實並不算多麼的複雜,一些基本的問題處理好就行——這也是這篇文章所想要說明的東西。因此這篇部落格只能算是記錄了一下寫一個遊戲過程中的一些思路,如果有同學也想要自己寫一個遊戲並

我的python的pygame學習之坦克大戰-引子

2018.04.13 author : wills 前段時間過清明節,整個人有點耍嗨了,部落格都沒咋寫。下面要給大家分享的是一個用pygame寫的經典坦克大戰遊戲,今天由於時間關係,我就不寫具體的程式碼,只是交代一下需要的東西。 首先你要有python

C++代碼之坦克大戰(1)

過程 核心 形狀 正方 遍歷 public 開始 www 保存 對坦克大戰情有獨鐘是因為大學時候第一次參加程序設計比賽就做的這個遊戲。當時用的語言是Java,那個比賽讓我悟出了面向對象的強大之處,我也是從那時開始接觸設計模式的。對我而言,坦克大戰有著非同尋常的意義,所以

C++代碼訓練之坦克大戰(2)

mbo calculate 人的 src ack 交流 學習過程 ima mta 這一篇中,我們繼續繼續進行我們的坦克大戰。 位置信息數據結構 在遊戲設計過程中,需要記錄大量的位置信息,如果僅僅使用(x,y)坐標很容易出錯。這一篇中,我們先定義兩個簡單的數據結構用來保存點

用javascript 面向對象制作坦克大戰(三)

scrip battle border 碰撞 type ges 實現 面向 gif   之前,我們完成了坦克的移動和地圖的繪制,這次我們來完成碰撞檢測和炮彈的發射。   上代碼前來張最新的類圖: 3. 碰撞檢測 前面我們已經完成了坦克的移動和地圖的繪制

javascript 面向對象制作坦克大戰 (一)

.com 希望 2.4 案例 1.2 如果 20px js面向對象 應該   PS:這個坦克大戰是在網上下的一段源碼之後,自己進行的重寫。 寫這個的目的是為了鞏固自己這段時間對js的學習。整理到博客上,算是對自己近端時間學習js的一個整理。 同時也希望可以幫助到學習

用javascript 面向對象制作坦克大戰(二)

初始化 common data- 插入 div 理解 span 們的 ava 2. 完善地圖 我們的地圖中有空地,墻,鋼,草叢,水,總部等障礙物。 我們可以把這些全部設計為對象。 2.1 創建障礙物對象群 對象群保存各種地圖上的對象,我們通過對象的屬

用javascript 面向對象制作坦克大戰(四)

一個 alt 希望 math ava load 初始化 lan 情況   我們現在還差一個重要的功能,沒錯,敵人坦克的創建以及子彈擊中敵人坦克時的碰撞檢測功能。 5. 創建敵人坦克完成炮彈碰撞檢測 5.1 創建敵人坦克對象   敵人坦克和玩家坦克一

超多經典 canvas 實例,動態離子背景、移動炫彩小球、貪吃蛇、坦克大戰、是男人就下100層、心形文字等等等

ntb contex lin 如果 maxwidth sel 容器 操作 reat 超多經典 canvas 實例 普及:<canvas> 元素用於在網頁上繪制圖形。這是一個圖形容器,您可以控制其每一像素,必須使用腳本來繪制圖形。 註意:IE 8 以及更早的版本不

新手小項目-java坦克大戰

set 人的 整體布局 邏輯關系 多次 截屏 目錄 布局管理 圖形 1.界面(圖形化-前端部分) 圖形化用於交互,不管是用文字形式給用戶選擇,還是圖形方式式的選擇都是一種交互方式。在java中如果我們需要用到圖形界面,就得想到GUI(Graphic user interf

坦克大戰0.2

fill class graphic 進行 image 分享 false init 背景色 using System; using System.Collections.Generic; using System.ComponentModel; using System.

面向對象經典案例坦克大戰

菜單 記錄 沒有 間隔 mes sets font 爆炸效果 private package Tank;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListe