pygame-漂浮物

簡介

同學出于好奇,在群里問了下網(wǎng)頁中漂浮物是怎么實現(xiàn)的俺叭,我覺得好玩也順手做了一個绪抛。
最終效果如下:

漂浮物

開發(fā)環(huán)境

  • windows10
  • pygame1.9.4
  • python3.6
  • 下載python配置好環(huán)境變量饥追,命令行執(zhí)行pip install pygame

構思

玩法

  • 漂浮物隨機漂浮
  • 漂浮物之間會連線纲刀,距離影響線條
  • 以鼠標位中心,吸引漂浮物均蜜,但不會吸引至中心

于是某個暑假回家就全憑印象李剖,做出了一只觸手怪。兆龙。杖爽。。紫皇。

觸手怪

反思

  • 漂浮物不會互相吸引
  • 被鼠標吸引的漂浮物慰安,會在邊界內自由移動(安全范圍)
  • 鼠標可視為一個隱形的漂浮物,例如id = 0的碎片
  • 需要兩個隊列聪铺,存放點和線

制作

游戲配置

# -*-coding:utf8-*-

import pygame
import sys
import random
from pygame.locals import *
from math import *

########## 配置 #############
SCREEN_SIZE = (1920, 1080)          #分辨率
MOUSE_LINK_RADIUS = 150             #鼠標連線范圍
MOUSE_SALF_RADIUS = 140             #鼠標安全范圍
MOUSE_ATTRACTION = 5                #鼠標吸引力
FRAGMENT_LINK_RADIUS = 100          #碎片連線范圍
FRAGMENT_SPEED = 40                 #碎片速度
FRAGMENT_MOUSE_ID = 0               #鼠標碎片ID
FRAGMENT_NUM = 100                  #碎片數(shù)量
FRAGMENT_COLOR = (135, 203, 219)    #碎片及線條顏色
  • 產(chǎn)生吸引力的范圍應該在(MOUSE_SALF_RADIUS 化焕, MOUSE_LINK_RADIUS )之間,容錯區(qū)域

向量類

class Vector():
    def __init__(self, pos):
        self.x, self.y = pos

    def __add__(self, vec):
        vec = Vector((self.x + vec.x, self.y + vec.y))
        return vec

    def __sub__(self, vec):
        vec = Vector((self.x - vec.x, self.y - vec.y))        
        return vec

    def __mul__(self, n):
        vec = Vector((self.x * n, self.y * n))
        return vec

    def get_val(self):
        return(self.x, self.y)

    def get_len(self):
        return sqrt(pow(self.x, 2) + pow(self.y, 2))

    def get_dir(self, vec):
        dist = self.get_dis(vec)
        if dist == 0: return 0
        return  Vector(((vec.x-self.x)/dist, (vec.y-self.y)/dist))

    def get_dis(self, vec):
        return sqrt(pow(vec.x-self.x, 2) + pow(vec.y-self.y, 2))

def rand_pos():
    return Vector((random.randint(0, SCREEN_SIZE[0]), random.randint(0, SCREEN_SIZE[1])))

def rand_vec():
    x = random.uniform(0, 1)
    while x == 0 or x == 1:
        x = random.uniform(0 ,1)

    return Vector((x, sqrt(1 - pow(x, 2))))
  • __add__铃剔、__sub__寫起來還是比add舒服

碎片類

class Fragment:
    frag_num = 0
    def __init__(self, pos, vec, speed):
        self.pos = pos
        self.vec = vec
        self.speed = speed
        self.id = self.__class__.frag_num
        self.__class__.frag_num += 1

    def is_mouse(self):
        return True if self.id == FRAGMENT_MOUSE_ID else False

    def move(self, time):
        if self.is_mouse():
            self.pos = Vector(pygame.mouse.get_pos())
        else:
            self.pos = self.pos + Vector((self.vec.x*self.speed*time, self.vec.y*self.speed*time))
            # 碰壁反彈
            if self.pos.x <= 0 or self.pos.x >= SCREEN_SIZE[0]:
                self.vec.x = -self.vec.x
                self.pos.x = 0 if self.pos.x <= 0 else SCREEN_SIZE[0]
            if self.pos.y <= 0 or self.pos.y >= SCREEN_SIZE[1]:
                self.vec.y = -self.vec.y
                self.pos.y = 0 if self.pos.y <= 0 else SCREEN_SIZE[1]

    def check_and_link(self, other):
        link_dis = MOUSE_LINK_RADIUS if self.is_mouse() else FRAGMENT_LINK_RADIUS
        if self.pos.get_dis(other.pos) < link_dis:
            self.link(other)

    def link(self, other):
        LinePool.append((self, other))

        if self.is_mouse():
            # 鼠標吸引撒桨,讓其逃不出范圍
            link_dis = self.pos.get_dis(other.pos)
            if link_dis < MOUSE_LINK_RADIUS + 5 and link_dis > MOUSE_SALF_RADIUS:
                link_dir = self.pos.get_dir(other.pos)
                other.pos = (other.pos - link_dir * MOUSE_ATTRACTION)

初始化

########## 各類初始化 #############
pygame.init()
screen = pygame.display.set_mode(SCREEN_SIZE, FULLSCREEN, 32)
clock = pygame.time.Clock()
FragPool = []
LinePool = []

# 造碎片
for i in range(FRAGMENT_NUM):
    FragPool.append(Fragment(rand_pos(), rand_vec(), FRAGMENT_SPEED))

畫線函數(shù)

def draw_all():
    # 碎片
    for frag in FragPool:
        if frag.is_mouse(): continue
        start1, stop1 = frag.pos.get_val(), (frag.pos + Vector((1, 1))).get_val()
        start2, stop2 = (frag.pos + Vector((1, 0))).get_val(), (frag.pos + Vector((0, 1))).get_val()
        pygame.draw.line(screen, FRAGMENT_COLOR, start1, stop1)
        pygame.draw.line(screen, FRAGMENT_COLOR, start2, stop2)

    # 連線
    for link in LinePool:
        start, stop = link
        dis = start.pos.get_dis(stop.pos)
        audius = MOUSE_LINK_RADIUS if start.is_mouse() else FRAGMENT_LINK_RADIUS
        color_pro = dis / audius
        color_line = []
        for i in FRAGMENT_COLOR:
            color_line.append(i*color_pro)
        pygame.draw.line(screen, color_line, start.pos.get_val(), stop.pos.get_val())
  • 由于pygame找不到合適的畫點函數(shù),所以選擇在碎片附近畫一個交叉線键兜。

游戲控制

while True:
    # 捕捉鍵盤鼠標凤类,按Esc退出
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
        if event.type == KEYDOWN and event.key == K_ESCAPE:
            exit()

    # 移動碎片并連線
    time_passed = clock.tick(60)
    time_passed_second = time_passed / 1000.0
    LinePool = []
    for frag in FragPool:
        frag.move(time_passed_second)
        now_id = frag.id + 1
        while now_id < len(FragPool):
            frag.check_and_link(FragPool[now_id])
            now_id += 1

    screen.fill((255, 255, 255))
    draw_all()
    pygame.display.update()

去年做的東西了,周末想一起寫上去普气。無奈只拭瞻蹋“觸手怪”代碼,“漂浮物”版本的找不到了现诀,只能重新寫了一個夷磕。
完整代碼在這

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末扼脐,一起剝皮案震驚了整個濱河市耗溜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌及塘,老刑警劉巖封锉,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绵跷,死亡現(xiàn)場離奇詭異膘螟,居然都是意外死亡,警方通過查閱死者的電腦和手機抖坪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門萍鲸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闷叉,“玉大人擦俐,你說我怎么就攤上這事∥詹啵” “怎么了蚯瞧?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長品擎。 經(jīng)常有香客問我埋合,道長,這世上最難降的妖魔是什么萄传? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任甚颂,我火速辦了婚禮,結果婚禮上秀菱,老公的妹妹穿的比我還像新娘振诬。我一直安慰自己,他們只是感情好衍菱,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布赶么。 她就那樣靜靜地躺著,像睡著了一般脊串。 火紅的嫁衣襯著肌膚如雪辫呻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天琼锋,我揣著相機與錄音放闺,去河邊找鬼。 笑死缕坎,一個胖子當著我的面吹牛怖侦,可吹牛的內容都是我干的。 我是一名探鬼主播念赶,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼础钠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了叉谜?” 一聲冷哼從身側響起旗吁,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎停局,沒想到半個月后很钓,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體香府,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年码倦,在試婚紗的時候發(fā)現(xiàn)自己被綠了企孩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡袁稽,死狀恐怖勿璃,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情推汽,我是刑警寧澤补疑,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站歹撒,受9級特大地震影響莲组,放射性物質發(fā)生泄漏。R本人自食惡果不足惜暖夭,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一锹杈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧迈着,春花似錦竭望、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至糕韧,卻和暖如春枫振,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背萤彩。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工粪滤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人雀扶。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓杖小,卻偏偏與公主長得像,于是被迫代替她去往敵國和親愚墓。 傳聞我的和親對象是個殘疾皇子予权,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內容