andy大宝 发表于 2025-8-28 17:19:29

Pygame纯画笔弹幕游戏(复制即玩)

本帖最后由 andy大宝 于 2026-9-26 20:18 编辑

Pygame学了不到一个星期,感觉发展空间比scratch大很多,有些scratch做不到的功能Pygame都能做到。
以前用scratch写的一个弹幕游戏,今天尝试用python复刻一下
再见,图形化编程ヽ(`Д&`)︵ ┻━┻

import pygame as pg
import sys
from random import *
from math import *

#pygame初始化
pg.init()
#设置窗口
window = pg.display.set_mode((800,600))         
pg.display.set_caption("game")

#设置弹幕速度
speed = 2
#设置角色坐标
mx = 400
my = 500

isOver = False
life = 10
score = 0

#每20个红色弹幕之后生成1个绿色弹幕
wait = 20

#设置按键重复
pg.key.set_repeat(1,10)
#获得字体
font = pg.font.Font(None,35)

#定义弹幕类
class Bullet():   
    x = 400
    y = 300
    ifDistory = False
    def __init__(self,colour):
      self.angle = pi / 180 * randint(0,359)
      self.colour = colour

#建立子弹库
every = []
   
while True:
   
    #处理按键事件
    for ev in pg.event.get():
      if ev.type == pg.QUIT:                  
            pg.quit()
            sys.exit()
   
      #角色控制
      elif ev.type == pg.KEYDOWN:
            if ev.key == pg.K_UP:
                my -= 2
            if ev.key == pg.K_DOWN:
                my += 2            
            if ev.key == pg.K_LEFT:
                mx -= 2
            if ev.key == pg.K_RIGHT:
                mx += 2
               
    if not isOver:            
      #增加弹幕数量
      every.append(Bullet("red"))
      if wait == 0:
            every.append(Bullet("green"))
            wait = 20
      else:
            wait -= 1
      #绘制背景
      window.fill("white")
      
      for i in every:
            #更改弹幕状态
            i.x += (speed * cos(i.angle))
            i.y -= (speed * sin(i.angle))
            #绘制弹幕
            pg.draw.circle(window,i.colour,(i.x,i.y),5,2)
            #边缘检测
            if i.x < 0 or i.x > 800 or i.y < 0 or i.y > 600:
                i.ifDistory = True
            #碰撞判定
            if ((i.x - mx) ** 2 + (i.y - my) ** 2) ** 0.5 <= 10:
                i.ifDistory = True
                if i.colour == "red":
                  life -= 1
                else:
                  score += 1

      for i in every:
            #删除弹幕
            if i.ifDistory == True:
                every.remove(i)
      
      #死亡判定
      if life <= 0 or mx < 0 or mx > 800 or my < 0 or my > 600:
            isOver = True
      #绘制角色
      pg.draw.circle(window,"black",(mx,my),5,2)

      #绘制文字
      window.blit(font.render("life:%s" % life,True,"black"),(20,20))
      window.blit(font.render("score:%s" % score,True,"black"),(20,60))
      #画面更新
      pg.display.update()
      #设置延迟
      pg.time.delay(10)

规则:
上下左右移动,红弹幕减血,绿弹幕加分,血量<=0或角色出边界时游戏结束
游戏截图:


关于bug与可玩性:
上下左右是按时间进行连续判定的,可能有判定不准的情况发生
因为这是用Pygame写游戏的第一次尝试,像难度调整,结算画面等都没能够完成,请各位大佬见谅{:10_303:} (也希望各位大佬能帮忙补全)



顺便说,我在代码里面添加了很多注释,但如果仍对代码内容有疑问,或有改进方案,欢迎提出^_^



andy大宝 发表于 2025-8-28 17:26:49

别问我为什么用纯画笔,或所有圈都长一个样,因为我不会碰撞检测,写代码时是用勾股定理算的{:10_266:}

gpa5031 发表于 2025-8-29 09:22:35

好历害啊

wxw2015 发表于 2025-8-29 17:27:41

报错:SyntaxError: multiple statements found while compiling a single stateme

尉尉的可乐 发表于 2025-8-29 18:26:07

看看

andy大宝 发表于 2025-8-29 18:37:56

wxw2015 发表于 2025-8-29 17:27
报错:SyntaxError: multiple statements found while compiling a single stateme

这段代码在我的设备上运行没有问题啊……
抱歉,我水平有限,不能解决你的报错问题。下面是AI提供的修改方案,如果还是不行的话再看看有没有大佬能提供建议吧:
import pygame as pg
import sys
from random import *
from math import *

# pygame初始化
pg.init()
# 设置窗口
window = pg.display.set_mode((800,600))         
pg.display.set_caption("game")

# 设置弹幕速度
speed = 2
# 设置角色坐标
mx = 400
my = 500

isOver = False
life = 10
score = 0

# 每20个红色弹幕之后生成1个绿色弹幕
wait = 20

# 设置按键重复
pg.key.set_repeat(1,10)
# 获得字体
font = pg.font.Font(None,35)

# 定义弹幕类
class Bullet():   
    def __init__(self, colour):
      self.x = 400
      self.y = 300
      self.ifDistory = False
      self.angle = pi / 180 * randint(0,359)
      self.colour = colour

# 建立子弹库
every = []

def main_game_loop():
    global mx, my, isOver, life, score, wait, every
   
    while True:
      # 处理按键事件
      for ev in pg.event.get():
            if ev.type == pg.QUIT:                  
                pg.quit()
                sys.exit()
      
            # 角色控制
            elif ev.type == pg.KEYDOWN:
                if ev.key == pg.K_UP:
                  my -= 2
                if ev.key == pg.K_DOWN:
                  my += 2            
                if ev.key == pg.K_LEFT:
                  mx -= 2
                if ev.key == pg.K_RIGHT:
                  mx += 2
                  
      if not isOver:            
            # 增加弹幕数量
            every.append(Bullet("red"))
            if wait == 0:
                every.append(Bullet("green"))
                wait = 20
            else:
                wait -= 1
            # 绘制背景
            window.fill("white")
            
            for i in every:
                # 更改弹幕状态
                i.x += (speed * cos(i.angle))
                i.y -= (speed * sin(i.angle))
                # 绘制弹幕
                pg.draw.circle(window, i.colour, (i.x, i.y), 5, 2)
                # 边缘检测
                if i.x < 0 or i.x > 800 or i.y < 0 or i.y > 600:
                  i.ifDistory = True
                # 碰撞判定
                if ((i.x - mx) ** 2 + (i.y - my) ** 2) ** 0.5 <= 10:
                  i.ifDistory = True
                  if i.colour == "red":
                        life -= 1
                  else:
                        score += 1

            for i in every[:]:# 使用切片创建副本,避免在迭代时修改列表
                # 删除弹幕
                if i.ifDistory:
                  every.remove(i)
            
            # 死亡判定
            if life <= 0 or mx < 0 or mx > 800 or my < 0 or my > 600:
                isOver = True
            # 绘制角色
            pg.draw.circle(window, "black", (mx, my), 5, 2)

            # 绘制文字
            window.blit(font.render("life:%s" % life, True, "black"), (20, 20))
            window.blit(font.render("score:%s" % score, True, "black"), (20, 60))
            # 画面更新
            pg.display.update()
            # 设置延迟
            pg.time.delay(10)

# 启动游戏
if __name__ == "__main__":
    main_game_loop()

尉尉的可乐 发表于 2025-8-29 19:44:42

还有回帖奖励?

季鑫 发表于 2025-8-29 21:40:41

1

ooolinux 发表于 2025-8-29 23:04:42

感谢分享,学习一下

薰衣草的花语 发表于 2025-8-30 13:58:24

红绿色盲怎么玩

zhangchenyvn 发表于 2025-8-31 13:07:41

薰衣草的花语 发表于 2025-8-30 13:58
红绿色盲怎么玩

我建议作者可以自选配色{:10_254:},这样既更好看,也更好玩{:10_279:}

G先行 发表于 2025-8-31 15:51:59

尉尉的可乐 发表于 2025-8-29 18:26
看看

1

G先行 发表于 2025-8-31 15:57:53

尉尉的可乐 发表于 2025-8-29 18:26
看看

1

尉尉的可乐 发表于 2025-8-31 16:24:41

G先行 发表于 2025-8-31 15:57
1

{:10_244:}

六翻了 发表于 2025-8-31 19:41:28

9

G先行 发表于 2025-9-1 09:20:16

薰衣草的花语 发表于 2025-8-30 13:58
红绿色盲怎么玩

1

小王高启 发表于 2025-9-1 17:06:15

我的发,牛

G先行 发表于 2025-9-1 19:17:32

六翻了 发表于 2025-8-31 19:41
9

1

G先行 发表于 2025-9-2 14:45:31

薰衣草的花语 发表于 2025-8-30 13:58
红绿色盲怎么玩

hhh

ypkyhj 发表于 2025-9-3 02:52:43

1
页: [1] 2 3
查看完整版本: Pygame纯画笔弹幕游戏(复制即玩)