wxPython和pycairo练习记录7

3天干完6个月的活,Claude把模型搬上AMD 一条挺刺激的消息:Anthropic 给投资人的材料里有一张幻灯片,写着它的 Claude Mythos Preview 只花了大约​,就摸清了怎么让另一个 Claude 模型在 AMD 的 MI355X 上跑起来。同一处还写了个对照数字:过去给一块新芯片做推理适配,通常要几十名工程师、​。3 天对 6 个月,这个比值太扎眼,当天中文互联网上就冒出一堆「英伟达的护城河塌了」的说法。我把能翻到的材料都翻了一遍,越看越觉得,塌掉的那一小块是真的,可塌的位置和很多人想的不一样。 阅读详情

wxPython和pycairo练习记录7

继续写障碍,选几个典型的来写。有个问题,有调用图片文件的类,每次生成新实例,都重新加载一次图片。应该把素材统一加载为全局变量,具体使用只需要引用素材变量。积重难返,记住这个教训,以后写其他的再注意吧。

7.1 铁块

刚想起障碍尺寸还有四分之一块的,之前的就不改了,这里铁块基础尺寸写成24*24大小。
在这里插入图片描述

class Iron(Obstacle):
    # 铁块
    def __init__(self, x, y):
        surface = self.Draw()
        super(Iron, self).__init__(x, y, surface)
        self._canCross = False # 不可穿行
        self._canDestroy = False # 不可打破
        self._layer = 0 # 层级,0 和坦克同一层
        self._canBulletCross = False # 子弹不可穿行
        self._buff = False # 没有特殊效果

    def Draw(self):
        # 尺寸24*24
        surface = cairo.ImageSurface(cairo.FORMAT_RGB24, 24, 24)
        ctx = cairo.Context(surface)
        # 底色
        ctx.set_source_rgb(0.7, 0.7, 0.7)
        ctx.paint()
        # 阴影
        ctx.move_to(0, 24)
        ctx.line_to(24, 24)
        ctx.line_to(24, 0)
        ctx.close_path()
        ctx.set_source_rgb(0.5, 0.5, 0.5)
        ctx.fill()
        # 高光
        ctx.rectangle(6, 6, 12, 12)
        ctx.set_source_rgb(1, 1, 1)
        ctx.fill()
        return surface

7.2 碉堡

它不同于普通障碍,检测到坦克到达一定范围就开始射击。不能无限制射击,不然就打成一条直线了,给武器类加上开火间隔时间。给障碍类新加 isRemote 属性,专门用于有远程作用的障碍。

因为是四方向的,只检测上下左右四个方向正方向是否有坦克经过。左上角坐标定位,实际检测坐标范围需要计算尺寸。
在这里插入图片描述

测试一下,碉堡图片找了两张图拼了一下。
在这里插入图片描述

class Blockhouse(Obstacle):
    # 碉堡
    def __init__(self, x, y, path="wall_blockhouse.png", radius=150):
        # 从文件加载 surface
        try:
            surface = cairo.ImageSurface.create_from_png(path)
        except IOError as e:
            print(e.message)

        super(Blockhouse, self).__init__(x, y, surface)

        self._canCross = False # 不可穿行
        self._canDestroy = True # 可打破
        self._layer = 0 # 层级,0 和坦克同一层
        self._canBulletCross = False # 子弹不可穿行
        self._buff = True # 有特殊效果
        self._isRemote = True # 有远程作用
        self._radius = radius # 火力覆盖半径
        self._direction = wx.WXK_UP # 射击方向

        # 加载武器和子弹
        self._weapon = Weapon(capacity=50, speed=1, interval=500)
        self._weapon.Loaded(self)
        for i in range(50):
            self._weapon.AddBullet(Bullet(type=3))

    def LoadWeapon(self, weapon):
        weapon.Loaded(self)
        self._weapon = weapon

    def GetWeapon(self):
        return self._weapon

    def GetRadius(self):
        return self._radius

    def GetDirection(self):
        return self._direction

    def Act(self, tank=None):
        # 向坦克调整射击方向并射击
        direction = tank.GetDirection()
        tx, ty, tw, th = tank.GetRect()
        x, y, w, h = self.GetRect()

        if tx > x - tw and tx < x + w:
            if ty < y:
                # print("up")
                self._direction = wx.WXK_UP
            else:
                # print("down")
                self._direction = wx.WXK_DOWN
            self._weapon.Fire()

        if ty > y - th and ty < y + h:
            if tx < x:
                # print("left")
                self._direction = wx.WXK_LEFT
            else:
                # print("right")
                self._direction = wx.WXK_RIGHT
            self._weapon.Fire()

7.3 泥坑

坦克经过泥坑速度就减为1,离开后速度恢复,需要给坦克父类添加速度读写方法。在哪存储原始速度呢?给坦克父类再加个原始速度属性。

那么怎么判断离开的动作?试试像碉堡一样给它也添加一个远程作用,作用半径设为它本身的尺寸1.5倍。也许远程作用可以独立出一个雷达…
在这里插入图片描述

找的图片有点像沙地,修修补补又三年。两块泥坑相邻,作用相互影响,把探测半径减到极小,也不太理想,暂时没想到怎么解决。

class Mud(Obstacle):
    # 泥坑
    def __init__(self, x, y, path="wall_mud.png"):
        # 从文件加载 surface
        try:
            surface = cairo.ImageSurface.create_from_png(path)
        except IOError as e:
            print(e.message)

        super(Mud, self).__init__(x, y, surface)

        self._canCross = True # 可穿行
        self._canDestroy = False # 不可打破
        self._layer = -1 # 子弹可以在泥坑上层飞过
        self._canBulletCross = True # 子弹可穿行
        self._buff = True # 有特殊效果
        self._isRemote = True # 有远程作用
        self._radius = self._width * 1.5 # 作用半径

    def GetRadius(self):
        return self._radius

    def Act(self, tank=None):
        # 离开范围
        tx, ty, tw, th = tank.GetRect()
        x, y, w, h = self.GetRect()
        if tank.GetSpeed() == 1 and (tx < x - tw or tx > x + w or ty < y - th or ty > y + h):
            tank.ResetSpeed()

    def SecondAct(self, tank=None):
        # 进入范围
        if tank.GetSpeed() > 1:
            tank.SetSpeed(1)

7.4 传送阵

两个传送阵,碰撞其中一个,传送到另一个传送阵位置。在传送阵上需要等待时间才能传送,不然无限互传。出传送阵范围,等待时间归零。
在这里插入图片描述

class Transmission(Obstacle):
    # 传送阵
    def __init__(self, x, y):
        surface = self.Draw()
        super(Transmission, self).__init__(x, y, surface)
        self._canCross = True # 可穿行
        self._canDestroy = False # 不可打破
        self._layer = -1 # 层级,0 和坦克同一层
        self._canBulletCross = True # 子弹可穿行
        self._buff = True # 没有特殊效果
        self._isRemote = True # 有远程作用
        self._radius = self._width * 1.5  # 作用半径
        self._waitTime = 3000 # 等待时间3秒
        self._dest = None # 传送目的法阵

    def GetRadius(self):
        return self._radius

    def Draw(self):
        # 画个六芒星
        surface = cairo.ImageSurface(cairo.FORMAT_RGB24, 48, 48)
        ctx = cairo.Context(surface)
        # 填充紫色底色
        ctx.set_source_rgb(0.27, 0.1, 0.47)
        ctx.paint()

        ctx.save()
        ctx.set_source_rgb(1, 1, 1)
        for i in range(2):
            if i == 1:
                # 对称翻转
                ctx.scale(1, -1)  # (x * dx, y * dy)
                ctx.translate(0, -48)  # 设置坐标轴原点
            # 画直角三角形
            ctx.move_to(0, 12)
            ctx.line_to(48, 12)
            ctx.line_to(24, 48)
            ctx.close_path()
            ctx.stroke()
        ctx.restore()

        # 紫色底不太明显,画四个角,标识下边缘
        ctx.set_source_rgb(0.6, 0.6, 0.6)
        for i in range(2):
            if i == 1:
                # 关于 x 轴对称
                ctx.scale(1, -1)
                ctx.translate(0, -48)
            for j in range(2):
                if j == 1:
                    # 关于 y 轴对称
                    ctx.scale(-1, 1)
                    ctx.translate(-48, 0)
                ctx.move_to(0, 6)
                ctx.line_to(0, 0)
                ctx.line_to(6, 0)
                ctx.close_path()
                ctx.fill()
        return surface

    def Act(self, tank=None):
        # 离开范围,等待时间归零
        tx, ty, tw, th = tank.GetRect()
        x, y, w, h = self.GetRect()
        if tx < x - tw or tx > x + w or ty < y - th or ty > y + h:
            tank.SetTransTime(0)

    def SecondAct(self, tank=None):
        # 进入法阵范围
        # 新进入,设置进入时间
        if tank.GetTransTime() == 0:
            tank.SetTransTime(cv.times * cv.SPEED)
        # 符合时间,开始传送
        if tank.GetTransTime() + self._waitTime <= cv.times * cv.SPEED:
            tank.SetX(self._dest.GetX())
            tank.SetY(self._dest.GetY())
            tank.SetTransTime(0)

    def Bind(self, transmission):
        # 法阵双向绑定
        self._dest = transmission
        transmission.SetDest(self)

    def GetDest(self):
        return self._dest

    def SetDest(self, dest):
        self._dest = dest

7.5 代码

# -*- coding: utf-8 -*-
# obstacle.py

import math
import wx
import cairo
from display import Sprite
from weapon import Weapon, Bullet
import board

class cv(board.cv):
    """
    常量,用类属性避免使用全局变量
    """
    # 面板尺寸
    BOARD_WIDTH = 600
    BOARD_HEIGHT = 400


class Obstacle(Sprite):
    def __init__(self, x, y, surface):
        # 重写 Sprite 的构造函数, 直接传入 surface
        self._x = x
        self._y = y
        self._destroyed = False # 销毁状态
        self._surface = surface
        # 获取图像尺寸
        self._width = self._surface.get_width()
        self._height = self._surface.get_height()

        self._canCross = False # 是否可穿行
        self._canDestroy = False # 是否可打破
        self._layer = 0 # 层级,0 和坦克同一层,-1 下层, 1 上层
        self._canBulletCross = False # 是否子弹可穿行
        self._buff = False # 是否有为有特殊效果的
        self._isRemote = False # 可远程作用

    def CanCross(self):
        return self._canCross

    def CanDestroy(self):
        return self._canDestroy

    def GetLayer(self):
        return self._layer

    def CanBulletCross(self):
        return self._canBulletCross

    def HasBuff(self):
        return self._buff

    def IsRemote(self):
        return self._isRemote

    def Act(self, tank=None):
        # 与坦克的交互行为,比如加滑行 _buff,比如碉堡直接开火
        pass

    def Update(self, times, speed):
        # 用于被定时器处理函数调用刷新,静态障碍不需要重写
        pass


class Brick(Obstacle):
    # 砖墙
    def __init__(self, x, y):
        surface = self.Draw() # 直接绘制砖墙
        super(Brick, self).__init__(x, y, surface)
        self._canCross = False # 不可穿行
        self._canDestroy = True # 可打破
        self._layer = 0 # 层级,0 和坦克同一层
        self._canBulletCross = False # 子弹不可穿行
        self._buff = False # 没有特殊效果

    def Draw(self):
        # 绘制砖墙
        # 按坦克尺寸48创建图像,颜色不需要透明
        surface = cairo.ImageSurface(cairo.FORMAT_RGB24, 48, 48)

        # 砖块是错落砌在一起的,先建一个2倍障碍宽度的矩形,作为一行砖块
        rect1 = cairo.ImageSurface(cairo.FORMAT_RGB24, 96, 12)

        # 画一个小24*12的矩形砖块,然后重复平铺
        rect2 = cairo.ImageSurface(cairo.FORMAT_RGB24, 24, 12)
        ctx = cairo.Context(rect2)
        # 填充灰色作底,水泥
        ctx.set_source_rgb(0.4, 0.4, 0.4)
        ctx.paint()
        # 画矩形,填充砖红色,砖
        ctx.set_source_rgb(0.6, 0.3, 0)
        ctx.rectangle(2, 2, 20, 8)
        ctx.fill()
        # 画线,更深的砖色,阴影
        ctx.set_source_rgb(0.42, 0.02, 0)
        ctx.set_line_width(4)
        ctx.move_to(3, 10)
        ctx.line_to(3, 3)
        ctx.line_to(22, 3)
        ctx.stroke()

        # 以 rect2 重复填充 rect1
        ctx = cairo.Context(rect1)
        pattern = cairo.SurfacePattern(rect2)
        pattern.set_extend(cairo.Extend.REPEAT)
        ctx.set_source(pattern)
        ctx.paint()

        # 把 rect1 错位绘制到 surface
        ctx = cairo.Context(surface)
        ctx.set_source_surface(rect1, -12, 0)
        ctx.paint()
        ctx.set_source_surface(rect1, 0, 12)
        ctx.paint()
        ctx.set_source_surface(rect1, -12, 24)
        ctx.paint()
        ctx.set_source_surface(rect1, 0, 36)
        ctx.paint()

        return surface


class Grass(Obstacle):
    # 草地
    def __init__(self, x, y, path="wall_grass.png"):
        # 从文件加载 surface
        try:
            surface = cairo.ImageSurface.create_from_png(path)
        except IOError as e:
            print(e.message)

        super(Grass, self).__init__(x, y, surface)

        self._canCross = True # 可穿行
        self._canDestroy = False # 不可打破
        self._layer = 1 # 层级,0 和坦克同一层
        self._canBulletCross = True # 子弹可穿行
        self._buff = False # 没有特殊效果


class Water(Obstacle):
    # 水面
    def __init__(self, x, y, path="wall_water.png"):
        # 从文件加载 surface
        try:
            surface = cairo.ImageSurface.create_from_png(path)
        except IOError as e:
            print(e.message)

        super(Water, self).__init__(x, y, surface)

        self._canCross = False # 不可穿行
        self._canDestroy = False # 不可打破
        self._layer = -1 # 子弹可以在水面上层飞过
        self._canBulletCross = True # 子弹可穿行
        self._buff = False # 没有特殊效果


class Ice(Obstacle):
    # 冰面
    def __init__(self, x, y):
        surface = self.Draw()
        super(Ice, self).__init__(x, y, surface)
        self._canCross = True # 可穿行
        self._canDestroy = False # 不可打破
        self._layer = -1 # 层级,0 和坦克同一层
        self._canBulletCross = True # 子弹可穿行
        self._buff = True # 有特殊效果
        self._distance = 20 # 滑行距离

    def Draw(self):
        surface = cairo.ImageSurface(cairo.FORMAT_RGB24, 48, 48)
        ctx = cairo.Context(surface)
        # 填充底色
        ctx.set_source_rgb(0.1, 0.85, 0.95)
        ctx.paint()

        # 以中心逆向旋转45度
        ctx.translate(24, 24)
        ctx.rotate(math.pi * 3 / 4)
        ctx.translate(-24, -24)

        # 画几条表示冰面纹理的线
        ctx.set_source_rgb(0, 0.64, 0.8)
        for i in range(10):
            if i % 2 == 0:
                ctx.set_dash([5, 1])
            else:
                ctx.set_dash([10, 15])

            ctx.move_to(-10, 6 * i)
            ctx.line_to(70, 6 * i)
            ctx.stroke()

        return surface

    def Act(self, tank=None):
        # 与坦克的交互行为,比如加滑行 _buff,比如碉堡直接开火
        direction = tank.GetDirection()
        x = tank.GetX()
        y = tank.GetY()
        if direction == wx.WXK_UP:
            tank.SetY(y - self._distance)
        elif direction == wx.WXK_DOWN:
            tank.SetY(y + self._distance)
        elif direction == wx.WXK_LEFT:
            tank.SetX(x - self._distance)
        elif direction == wx.WXK_RIGHT:
            tank.SetX(x + self._distance)


class Iron(Obstacle):
    # 铁块
    def __init__(self, x, y):
        surface = self.Draw()
        super(Iron, self).__init__(x, y, surface)
        self._canCross = False # 不可穿行
        self._canDestroy = False # 不可打破
        self._layer = 0 # 层级,0 和坦克同一层
        self._canBulletCross = False # 子弹不可穿行
        self._buff = False # 没有特殊效果

    def Draw(self):
        # 尺寸24*24
        surface = cairo.ImageSurface(cairo.FORMAT_RGB24, 24, 24)
        ctx = cairo.Context(surface)
        # 底色
        ctx.set_source_rgb(0.7, 0.7, 0.7)
        ctx.paint()
        # 阴影
        ctx.move_to(0, 24)
        ctx.line_to(24, 24)
        ctx.line_to(24, 0)
        ctx.close_path()
        ctx.set_source_rgb(0.5, 0.5, 0.5)
        ctx.fill()
        # 高光
        ctx.rectangle(6, 6, 12, 12)
        ctx.set_source_rgb(1, 1, 1)
        ctx.fill()
        return surface


class Blockhouse(Obstacle):
    # 碉堡
    def __init__(self, x, y, path="wall_blockhouse.png", radius=150):
        # 从文件加载 surface
        try:
            surface = cairo.ImageSurface.create_from_png(path)
        except IOError as e:
            print(e.message)

        super(Blockhouse, self).__init__(x, y, surface)

        self._canCross = False # 不可穿行
        self._canDestroy = True # 可打破
        self._layer = 0 # 层级,0 和坦克同一层
        self._canBulletCross = False # 子弹不可穿行
        self._buff = True # 有特殊效果
        self._isRemote = True # 有远程作用
        self._radius = radius # 火力覆盖半径
        self._direction = wx.WXK_UP # 射击方向

        # 加载武器和子弹
        self._weapon = Weapon(capacity=50, speed=1, interval=500)
        self._weapon.Loaded(self)
        for i in range(50):
            self._weapon.AddBullet(Bullet(type=3))

    def LoadWeapon(self, weapon):
        weapon.Loaded(self)
        self._weapon = weapon

    def GetWeapon(self):
        return self._weapon

    def GetRadius(self):
        return self._radius

    def GetDirection(self):
        return self._direction

    def Act(self, tank=None):
        # 向坦克调整射击方向并射击
        direction = tank.GetDirection()
        tx, ty, tw, th = tank.GetRect()
        x, y, w, h = self.GetRect()

        if tx > x - tw and tx < x + w:
            if ty < y:
                # print("up")
                self._direction = wx.WXK_UP
            else:
                # print("down")
                self._direction = wx.WXK_DOWN
            self._weapon.Fire()

        if ty > y - th and ty < y + h:
            if tx < x:
                # print("left")
                self._direction = wx.WXK_LEFT
            else:
                # print("right")
                self._direction = wx.WXK_RIGHT
            self._weapon.Fire()


class Mud(Obstacle):
    # 泥坑
    def __init__(self, x, y, path="wall_mud.png"):
        # 从文件加载 surface
        try:
            surface = cairo.ImageSurface.create_from_png(path)
        except IOError as e:
            print(e.message)

        super(Mud, self).__init__(x, y, surface)

        self._canCross = True # 可穿行
        self._canDestroy = False # 不可打破
        self._layer = -1 # 子弹可以在泥坑上层飞过
        self._canBulletCross = True # 子弹可穿行
        self._buff = True # 有特殊效果
        self._isRemote = True # 有远程作用
        self._radius = self._width * 1.5 # 作用半径

    def GetRadius(self):
        return self._radius

    def Act(self, tank=None):
        # 离开范围
        tx, ty, tw, th = tank.GetRect()
        x, y, w, h = self.GetRect()
        if tank.GetSpeed() == 1 and (tx < x - tw or tx > x + w or ty < y - th or ty > y + h):
            tank.ResetSpeed()

    def SecondAct(self, tank=None):
        # 进入范围
        if tank.GetSpeed() > 1:
            tank.SetSpeed(1)


class Transmission(Obstacle):
    # 传送阵
    def __init__(self, x, y):
        surface = self.Draw()
        super(Transmission, self).__init__(x, y, surface)
        self._canCross = True # 可穿行
        self._canDestroy = False # 不可打破
        self._layer = -1 # 层级,0 和坦克同一层
        self._canBulletCross = True # 子弹可穿行
        self._buff = True # 没有特殊效果
        self._isRemote = True # 有远程作用
        self._radius = self._width * 1.5  # 作用半径
        self._waitTime = 3000 # 等待时间3秒
        self._dest = None # 传送目的法阵

    def GetRadius(self):
        return self._radius

    def Draw(self):
        # 画个六芒星
        surface = cairo.ImageSurface(cairo.FORMAT_RGB24, 48, 48)
        ctx = cairo.Context(surface)
        # 填充紫色底色
        ctx.set_source_rgb(0.27, 0.1, 0.47)
        ctx.paint()

        ctx.save()
        ctx.set_source_rgb(1, 1, 1)
        for i in range(2):
            if i == 1:
                # 对称翻转
                ctx.scale(1, -1)  # (x * dx, y * dy)
                ctx.translate(0, -48)  # 设置坐标轴原点
            # 画直角三角形
            ctx.move_to(0, 12)
            ctx.line_to(48, 12)
            ctx.line_to(24, 48)
            ctx.close_path()
            ctx.stroke()
        ctx.restore()

        # 紫色底不太明显,画四个角,标识下边缘
        ctx.set_source_rgb(0.6, 0.6, 0.6)
        for i in range(2):
            if i == 1:
                # 关于 x 轴对称
                ctx.scale(1, -1)
                ctx.translate(0, -48)
            for j in range(2):
                if j == 1:
                    # 关于 y 轴对称
                    ctx.scale(-1, 1)
                    ctx.translate(-48, 0)
                ctx.move_to(0, 6)
                ctx.line_to(0, 0)
                ctx.line_to(6, 0)
                ctx.close_path()
                ctx.fill()
        return surface

    def Act(self, tank=None):
        # 离开范围,等待时间归零
        tx, ty, tw, th = tank.GetRect()
        x, y, w, h = self.GetRect()
        if tx < x - tw or tx > x + w or ty < y - th or ty > y + h:
            tank.SetTransTime(0)

    def SecondAct(self, tank=None):
        # 进入法阵范围
        # 新进入,设置进入时间
        if tank.GetTransTime() == 0:
            tank.SetTransTime(cv.times * cv.SPEED)
        # 符合时间,开始传送
        if tank.GetTransTime() + self._waitTime <= cv.times * cv.SPEED:
            tank.SetX(self._dest.GetX())
            tank.SetY(self._dest.GetY())
            tank.SetTransTime(0)

    def Bind(self, transmission):
        # 法阵双向绑定
        self._dest = transmission
        transmission.SetDest(self)

    def GetDest(self):
        return self._dest

    def SetDest(self, dest):
        self._dest = dest

# -*- coding: utf-8 -*-
# example3.py

import random
import math
import wx
import wx.lib.wxcairo
import cairo
import board
from display import MovieClip
from tank import Player, Enemy
from weapon import Weapon, Bullet
from obstacle import *

class cv(board.cv):
    """
    常量,用类属性避免使用全局变量
    """
    # 面板尺寸
    BOARD_WIDTH = 600
    BOARD_HEIGHT = 400


class Board(board.Board):
    def DrawBackground(self, ctx):
        super().DrawBackground(ctx)

        text = "SmileBasic"
        ctx.set_font_size(40)
        _, _, w, h, _, _ = ctx.text_extents(text)
        x = (cv.BOARD_WIDTH - w) // 2
        y = (cv.BOARD_HEIGHT - h) // 2

        # 文字是以首个字左下角坐标定位,而矩形是以左上角定位,y轴相差文字的高度,不需要考虑线条宽度。
        # 另外PaintDC是不含标题栏的。
        ctx.rectangle(x - 10, y - 10 - h, w + 20, h + 20)
        ctx.set_source_rgb(1, 0, 0)
        ctx.stroke()

        ctx.move_to(x, y)
        ctx.set_source_rgb(1, 1, 1)
        ctx.show_text(text)

    def InitSceneObjects(self):
        super().InitSceneObjects()
        self.InitPlayer()
        self.InitObstacles()

    def InitPlayer(self):
        self.player = Player(60, 50) # 实例化一个玩家坦克
        self.sceneObjects.append(self.player)

        # 初始武器系统,并装弹
        self.bullets = []
        weapon = Weapon(capacity=100, speed=2)
        for i in range(50):
            bullet = Bullet(type=3) # 装载第4行子弹
            weapon.AddBullet(bullet)
            self.bullets.append(bullet)
            self.sceneObjects.append(bullet)

            bullet = Bullet(type=6) # 装载第7行子弹
            weapon.AddBullet(bullet)
            self.bullets.append(bullet)
            self.sceneObjects.append(bullet)
        self.player.LoadWeapon(weapon) # 玩家坦克加载武器系统

    def InitObstacles(self):
        self.obstacles = []
        # 生成4个砖墙
        brick1 = Brick(10, 50)
        brick2 = Brick(58, 98)
        brick3 = Brick(106, 98)
        brick4 = Brick(230, 220)
        # 生成1个草地
        grass = Grass(300, 50)
        # 生成1个水面
        water = Water(360, 50)
        # 生成1个冰面
        ice = Ice(230, 50)
        # 生成3个小铁块
        iron1 = Iron(230, 120)
        iron2 = Iron(254, 120)
        iron3 = Iron(254, 144)
        # 生成碉堡
        blockhouse = Blockhouse(10, 220)
        # 需要把碉堡子弹也加入对象列表进行绘制和碰撞检测
        self.bullets += blockhouse.GetWeapon().GetClip()
        self.sceneObjects += blockhouse.GetWeapon().GetClip()
        # 生成两个泥坑
        mud1 = Mud(290, 220)
        mud2 = Mud(338, 220)
        # 生成两个传送阵
        transmission1 = Transmission(390, 220)
        transmission2 = Transmission(500, 120)
        transmission1.Bind(transmission2)
        self.obstacles += [brick1, brick2, brick3, brick4, grass, water,
                           ice, iron1, iron2, iron3, blockhouse, mud1, mud2, transmission1, transmission2]
        self.sceneObjects += [brick1, brick2, brick3, brick4, grass, water,
                              ice, iron1, iron2, iron3, blockhouse, mud1, mud2, transmission1, transmission2]

    def DrawSceneObjects(self, ctx):
        # print("绘制", self.player.GetRect())
        # 后绘制的对象在上层显示
        for obstacle in self.obstacles:
            if obstacle.GetLayer() == -1:
                self.DrawSprite(ctx, obstacle)

        self.DrawSprite(ctx, self.player)

        for bullet in self.bullets:
            self.DrawSprite(ctx, bullet)

        for obstacle in self.obstacles:
            if obstacle.GetLayer() >= 0:
                self.DrawSprite(ctx, obstacle)

    def DrawSprite(self, ctx, sprite):
        ctx.set_source_surface(sprite.GetSurface(), sprite.GetX(), sprite.GetY())
        ctx.paint()

    def OnKeyDown(self, e):
        self.player.OnKeyDown(e)
        self.Refresh()

    def OnKeyUp(self, e):
        self.player.OnKeyUp(e)

    def CheckStrategies(self):
        self.CheckCollisions()

    def CheckCollisions(self):
        # 检测子弹砖墙碰撞
        # print("碰撞检测", self.player.GetRect())
        for obstacle in self.obstacles[:]:
            # 子弹可穿行,则跳过检测
            if obstacle.CanBulletCross():
                continue

            rect = obstacle.GetRect()
            for bullet in self.bullets[:]:
                if rect.Intersects(bullet.GetRect()):
                    # 如果可摧毁,则碰撞后子弹和障碍都销毁
                    if obstacle.CanDestroy():
                        obstacle.Destroy()
                        self.obstacles.remove(obstacle)
                        self.sceneObjects.remove(obstacle)

                    bullet.Destroy()
                    self.bullets.remove(bullet)
                    self.sceneObjects.remove(bullet)
                    break

        # 检测坦克和砖墙碰撞,碰撞后坦克位置重置
        for obstacle in self.obstacles[:]:
            # 坦克可穿行并且没有特殊效果,则跳过检测
            if obstacle.CanCross() and not obstacle.HasBuff():
                continue

            rect = obstacle.GetRect()
            if obstacle.IsRemote():
                x, y, w, h = rect
                radius = obstacle.GetRadius()
                # 根据作用半径求出扩大范围后的矩形参数,因为是四方向,所以半径为一半边长
                x = x - (radius - w / 2)
                y = y - (radius - h / 2)
                width = height = radius * 2
                rect = wx.Rect(x, y, width, height)

            if rect.Intersects(self.player.GetRect()):
                # print("检测到碰撞", self.player.GetRect())

                # 如果有特殊效果则只不执行后续位置重置
                if obstacle.HasBuff():
                    obstacle.Act(self.player)
                    # 无远程作用障碍跳过
                    if not obstacle.IsRemote():
                        continue
                    # 远程作用障碍判断障碍本身与坦克碰撞
                    rect = obstacle.GetRect()
                    if not rect.Intersects(self.player.GetRect()):
                        continue
                    # buff + 远程作用 + 能通行 + 本身碰撞,二次作用,泥坑定制
                    if obstacle.CanCross():
                        obstacle.SecondAct(self.player)
                        continue

                direction = self.player.GetDirection()
                x, y, w, h = rect
                _, _, pw, ph = self.player.GetRect()
                if direction == wx.WXK_UP:
                    self.player.SetY(y + h)
                elif direction == wx.WXK_DOWN:
                    self.player.SetY(y - ph)
                elif direction == wx.WXK_LEFT:
                    self.player.SetX(x + w)
                elif direction == wx.WXK_RIGHT:
                    self.player.SetX(x - pw)
                # print("碰撞重置为", self.player.GetRect())


# -*- coding: utf-8 -*-
# weapon.py

import wx
import wx.lib.wxcairo
import cairo
from display import MovieClip
import board


class cv(board.cv):
    """
    常量,用类属性避免使用全局变量
    """
    # 面板尺寸
    BOARD_WIDTH = 600
    BOARD_HEIGHT = 400


class Weapon:
    def __init__(self, capacity=10, speed=20, interval=100):
        self._clip = [] # 弹夹
        self._capacity = capacity # 弹夹容量
        self._speed = speed # 发射出的子弹速度
        self._isFire = False # 开火状态
        self._tank = None # 被装载对象
        self._currentBullet = None # 当前要发射的子弹
        self._fireTime = -interval - 1 # 上次开火时间,首次开火时间必然满足
        self._fireInterval = interval # 默认开火间隔时间0.1秒

    def GetCapacity(self):
        return self._capacity

    def GetSpeed(self):
        return self._speed

    def GetBulletNum(self):
        return len(self._clip)

    def GetClip(self):
        return self._clip

    def isFire(self):
        return self._isFire

    def Loaded(self, tank):
        # 被装载
        self._tank = tank

    def AddBullet(self, bullet):
        # 装弹并返回装弹结果
        if len(self._clip) < self._capacity:
            self._clip.append(bullet)
            return True
        else:
            return False

    def Fire(self, state=True):
        # 开火或停火
        self._isFire = state
        # 判断状态及开火间隔时间是否大于武器限定间隔时间
        if state and (self._fireTime + self._fireInterval) < cv.times * cv.SPEED and len(self._clip) > 0:
            # 记录开火时间
            self._fireTime = cv.times * cv.SPEED
            self._currentBullet = self._clip.pop()
            # 根据坦克坐标和尺寸计算子弹起始位置
            direction = self._tank.GetDirection()
            x, y, w, h = self._tank.GetRect()
            _, _, bw, bh = self._currentBullet.GetRect()

            if direction == wx.WXK_UP:
                bx = x + w / 2 - bw / 2
                by = y - bh
            elif direction == wx.WXK_DOWN:
                bx = x + w / 2 - bw / 2
                by = y + h
            elif direction == wx.WXK_LEFT:
                bx = x - bw
                by = y + h / 2 - bh / 2
            elif direction == wx.WXK_RIGHT:
                bx = x + w
                by = y + h / 2 - bh / 2

            # 设置子弹方向
            self._currentBullet.SetDirection(direction)
            # 设置发射初始坐标
            self._currentBullet.SetX(bx)
            self._currentBullet.SetY(by)
            # 设置子弹速度
            self._currentBullet.SetSpeed(self._speed)
            # 发射
            self._currentBullet.Fired()


class Bullet(MovieClip):
    def __init__(self, x=-100, y=0, path="bullets.png", rect=(0, 0, 16, 16), fps=100, type=0):
        super(Bullet, self).__init__(x, y, path, rect, fps)
        self._speed = 0 # 子弹初始速度
        self._type = type
        self._direction = None

    def SetDirection(self, direction):
        self._direction = direction

    def SetSpeed(self, speed):
        self._speed = speed

    def Fired(self):
        # 尽量只用中心对称的子弹,避免换方向发射还要做旋转处理
        self.GotoAndPlay(0, self._type)

    def Fly(self):
        if not self._destroyed and self._speed > 0:
            if self._direction == wx.WXK_UP:
                self._y -= self._speed
            elif self._direction == wx.WXK_DOWN:
                self._y += self._speed
            elif self._direction == wx.WXK_LEFT:
                self._x -= self._speed
            elif self._direction == wx.WXK_RIGHT:
                self._x += self._speed

    def Update(self, times, speed):
        self.Fly()
        super().Update(times, speed)

# -*- coding: utf-8 -*-
# tank.py

import random
import wx
import wx.lib.wxcairo
import cairo
from display import MovieClip
import board


class cv(board.cv):
    """
    常量,用类属性避免使用全局变量
    """
    # 面板尺寸
    BOARD_WIDTH = 600
    BOARD_HEIGHT = 400


class Tank(MovieClip):
    def __init__(self, *args, **kwargs):
        super(Tank, self).__init__(*args, **kwargs)
        self._speed = 10 # 移动速度
        self._dx = 0 # x 轴方向
        self._dy = 0 # y 轴方向
        self._weapon = None # 武器
        self._originSpeed = 10 # 原始速度,用于恢复
        self._transTime = 0 # 等待法阵传送时间

    def Up(self):
        self._dy = -1
        self._dx = 0
        # 同一方向时需要需要排除,不然动画一直停留在第1帧
        if self._currentScene != 0:
            self.GotoAndPlay(0, 0)

    def Down(self):
        self._dy = 1
        self._dx = 0

        if self._currentScene != 1:
            self.GotoAndPlay(0, 1)

    def Left(self):
        self._dx = -1
        self._dy = 0

        if self._currentScene != 2:
            self.GotoAndPlay(0, 2)

    def Right(self):
        self._dx = 1
        self._dy = 0

        if self._currentScene != 3:
            self.GotoAndPlay(0, 3)

    def LoadWeapon(self, weapon):
        weapon.Loaded(self)
        self._weapon = weapon

    def GetWeapon(self):
        return self._weapon

    def GetSpeed(self):
        return self._speed

    def SetSpeed(self, speed):
        self._speed = speed

    def ResetSpeed(self):
        self._speed = self._originSpeed

    def GetTransTime(self):
        return self._transTime

    def SetTransTime(self, time):
        self._transTime = time


class Player(Tank):
    def __init__(self, x, y, path="tank_T1_0.png", rect=(0, 0, 48, 48), fps=100):
        super(Player, self).__init__(x, y, path, rect, fps)
        self._direction = wx.WXK_UP

    def OnKeyDown(self, e):
        key = e.GetKeyCode()

        if key == wx.WXK_UP:
            self.Up()
            self._direction = wx.WXK_UP
        if key == wx.WXK_DOWN:
            self.Down()
            self._direction = wx.WXK_DOWN
        if key == wx.WXK_LEFT:
            self.Left()
            self._direction = wx.WXK_LEFT
        if key == wx.WXK_RIGHT:
            self.Right()
            self._direction = wx.WXK_RIGHT

        self._x += self._dx * self._speed
        self._y += self._dy * self._speed

        # 开火
        if key == wx.WXK_SPACE and self._weapon:
            self._weapon.Fire(True)

    def OnKeyUp(self, e):
        key = e.GetKeyCode()

        if key == wx.WXK_UP or key == wx.WXK_DOWN:
            self._dy = 0
        if key == wx.WXK_LEFT or key == wx.WXK_RIGHT:
            self._dx = 0
        if self._dx == 0 and self._dy == 0:
            self.Stop()

        # 停火
        if key == wx.WXK_SPACE and self._weapon:
            self._weapon.Fire(False)

    def GetDirection(self):
        return self._direction

class Enemy(Tank):
    def __init__(self, x, y, path="tank_T1_0.png", rect=(0, 0, 48, 48), fps=100, mixColor=(0, 1, 1, 0.8)):
        self._mixColor = mixColor # 自定义混合颜色
        super(Enemy, self).__init__(x, y, path, rect, fps)
        # 初始随机方向
        self._direction = random.choice([wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT, wx.WXK_RIGHT])
        self._speed = 1
        self._originSpeed = 1
        self._isPlaying = True

    def LoadFrames(self, rect):
        # 将图像载为帧前,先改变图像的色相
        surface = cairo.ImageSurface.create_from_png("tank_T1_0.png")
        sw = surface.get_width()
        sh = surface.get_height()

        # 创建只显示坦克的 surface 作为混合层
        surface2 = cairo.ImageSurface(cairo.FORMAT_ARGB32, sw, sh)
        ctx = cairo.Context(surface2)
        ctx.set_source_rgba(*self._mixColor)
        ctx.mask_surface(surface)

        # 与目标图像混合
        ctx = cairo.Context(surface)
        ctx.set_source_surface(surface2)
        ctx.set_operator(cairo.Operator.HSL_HUE) # 将色相和目标图像色相混合
        ctx.paint()

        self._surface = surface
        super().LoadFrames(rect)

    def GetDirection(self):
        return self._direction

    def SetDirection(self, direction):
        self._direction = direction

    def ChangeDirection(self, direction):
        # 方向转换为除指定方向以外的方向,总觉得这样写不太好 加个
        # TODO
        directions = [wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT, wx.WXK_RIGHT]
        directions.remove(direction)
        self._direction = random.choice(directions)

    def AutoWalk(self):
        if self._direction == wx.WXK_UP:
            self.Up()
        elif self._direction == wx.WXK_DOWN:
            self.Down()
        elif self._direction == wx.WXK_LEFT:
            self.Left()
        elif self._direction == wx.WXK_RIGHT:
            self.Right()

        # 遇边界转向,坦克宽高明明是48,可是按48处理显示不对
        # TODO
        if self._x < 0:
            self._x = 0
            self.ChangeDirection(wx.WXK_LEFT)
        elif self._x > cv.BOARD_WIDTH - 68:
            self._x = cv.BOARD_WIDTH - 68
            self.ChangeDirection(wx.WXK_RIGHT)
        else:
            self._x += self._dx * self._speed

        if self._y < 0:
            self._y = 0
            self.ChangeDirection(wx.WXK_UP)
        elif self._y > cv.BOARD_HEIGHT - 96:
            self._y = cv.BOARD_HEIGHT - 96
            self.ChangeDirection(wx.WXK_DOWN)
        else:
            self._y += self._dy * self._speed

    def Update(self, times, speed):
        # 由主程序刷新时更新
        self.AutoWalk()
        super().Update(times, speed)

如何处理动态语言(Python / JS)的“隐形”调用链? 本文揭示动态语言(Python/JS)中静态AST解析导致调用链“断链”的核心问题,提出通过运行时追踪补全图谱的解决方案。基于Code-Graph-RAG的cgr trace机制,分别利用pytest插件与V8 Profiler捕获真实调用路径,将动态边合并至静态图谱,并在权重体系中提升动态边优先级。实践表明,该方法可显著提升图谱覆盖率,实现“结构+行为”双视角理解代码,为MCP与Rerank系统提供可靠支持。 阅读详情

相关推荐

.NET适配HarmonyOS进展 1. 前言

目前国产化系统浪潮下,适配鸿蒙是中国软件大势所趋,.NET作为最适合开发客户端语言之一,适配鸿蒙系统(HarmonyOS Next)是目前.NET开发者最关心的事情。我目前业余时间正在移植Avalonia到HarmonyOS,去年在.NET Conf CN上分享过,目前又取得一点进展,所以本文把所有问题进行整合与大家进行分享。

2301_76476890的博客 1461

wxPython的键盘事件Keycodes(键值)

在wxPython API Class KeyEvent 可以查到相关函数 使用方法 key = event.GetKeyCode()  #获得键盘事件的键值 if key == wx.WXK_TAB:#事实上,事件接受的是ASCII码,可以通过chr(key)获得实际的字符(字母+数字)      pass 实际上,wx.WXK_TAB这些都是是ASCII码表的另外一种表示。使用中仍然

技术皮皮虾 9313

PackML工业标准解析:统一机器状态管理与数据交换的实践指南

在工业自动化与智能制造领域,实现设备间的互联互通与高效协同是核心挑战。这背后依赖于一套标准化的机器行为与数据交换规范,其原理在于通过定义统一的状态模型与接口协议,消除不同厂商设备间的“语言”隔阂。这项技术的核心价值在于大幅降低系统集成复杂度、提升运维效率与生产透明度,是构建数字化工厂的基石。其典型应用场景包括包装机械、离散制造产线等需要多设备协同的领域。本文聚焦的PackML(包装机械语言)标准,正是这一理念的杰出实践,它通过一套严谨的**状态机模型**和**数据标签(PackTags)** 体系,为机器提

weixin_30070339的博客 403

wxPython和pycairo练习记录10

一开始考虑不全面,后面写的时候就只有一个心思,烂代码,完成就好。代码创建控件实例是个痛苦的过程,因为做的基本都是重复的事,能用循环的最好写进循环,熟悉控件后推荐用 wxFromBuilder。

SmileBasic的博客 568

【Nordic实战】nRF54L15引脚规划:电源域、专用引脚与低功耗设计避坑指南

本文深入解析Nordic nRF54L15芯片的引脚规划策略,重点阐述其基于电源域(MCU域、PERI域、LP域)的GPIO分配原则。文章提供了从思维转变到实战避坑的完整指南,强调遵循专用引脚与域对应关系是实现超低功耗设计的关键,并分享了系统化的引脚规划流程与工具使用建议。

weixin_29192141的博客 321

数据权限设计

随着IT新技术不断完善成熟,企业数字化建设得到全面的发展,数据将成为一个创造财富的重要来源,并且越来越多地被视为一项值得重视的企业资产。未来,很多企业之间的竞争,其实也是资源和数据竞争。那么针对数据资产,如何保障它的安全性呢?数据的权限管理无疑是必不可少的。数据权限从数据源来控制不同的用户能够查看、使用和授权不同的数据表数据(其实就是数据表行列的管控),就如同筑起了一道道护城墙,为数据安全提供了保障。

qq_40664711的博客 1万+

wxPython和pycairo练习记录8

经过障碍物的编写,发现需要停止前进并重新梳理一下。1.新的检测项加入时,已经在向混乱发展。是时候用上封装变化的编程工具,用策略模式或状态模式重写。2.显示,在基类引入层级和优先级,不同层低层级先绘制,同层高优先级先绘制。3.范围的碰撞和本身的碰撞的作用顺序。还有像已经实现的碉堡,只有一个外层碰撞区域,如果要多加几层呢,最外层出现坦克,射速为1,再近一层射速为5,最近一层射速达到20。

SmileBasic的博客 387

YOLO26小目标检测实战:STAL标签分配+MuSGD优化,VisDrone数据集漏检率降50%

小目标检测是计算机视觉的经典难题,而VisDrone数据集小目标占比极高:数据集中小目标(像素面积<32×32)占比超过60%,且大量目标仅为几个像素,特征信息极度匮乏;背景复杂且干扰多:无人机航拍场景包含建筑物、树木、人群、车辆等复杂背景,小目标易被背景淹没;尺度变化与遮挡严重:同一目标在不同帧中尺度差异大,且小目标极易被其他目标遮挡;传统模型的固有缺陷标签分配策略(如ATSS、SimOTA)偏向大目标,小目标的正样本分配不足,导致模型对小目标不敏感;

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1186

wxPython和pycairo练习记录1

学习,分为学和习,学完了不练习,让大脑觉得不重要,会忘记。所以,我决定练习并记录 wxPython 和 pycairo 的代码编写,如果你也想试试请自行配置环境。wxPython官网:https://www.wxpython.org/pycairo官网:https://cairographics.org/pycairo/本机环境:WIN10因为没有相关完整项目经验,所以不能把全局都设计好,先从基本的迭代。...

SmileBasic的博客 283

基于 YOLOv26 的食品包装缺陷检测系统:智能视觉质检方案

本文提出了一种基于YOLOv26深度学习的食品包装缺陷智能检测系统。该系统能够自动识别多种常见包装缺陷,包括密封不良、破损、污染、标签错误等8类问题。相比传统人工检测方法,该系统具有高精度、多类别分类、实时推理等优势。文章详细介绍了系统架构,包含数据采集、预处理、YOLOv26检测模型和后处理四个核心模块,并提供了完整的环境配置和数据处理代码实现。该系统为食品包装行业提供了一种高效、准确的智能视觉质检解决方案。

一键难忘的博客 687

鸿蒙系统开发工程师:核心技术解析与深度面试指南

摘要: 鸿蒙系统开发工程师需具备底层驱动开发、系统移植优化及分布式架构能力。核心职责包括硬件适配(Bootloader、内核移植、HDF驱动开发)、性能调优(启动加速、功耗管理)及稳定性保障。技术要求涵盖C/C++编程、Linux内核机制、鸿蒙架构(HDF、分布式服务)及ArkTS/ArkUI基础。面试重点考察系统移植流程(如ARM板适配)、驱动开发(I2C/Display)、性能优化手段及内存/同步机制的应用。

郑伟强dev的专栏 430

wxPython和pycairo练习记录4

继续写碰撞检测。

SmileBasic的博客 306

C++面试八股文

和静态多态(又称编译期多态,即在系统编译期间就可以确定程序将要执行哪个函数),其中动态多态是通过虚函数实现的,虚函数是类的成员函数,存在存储虚函数指针的表叫做虚函数表,虚函数表是一个存储类成员虚函数的指针,每个指针都指向调用它的地方,当子类调用虚函数时,就会去虚表里面找自己对应的函数指针,从而实现“谁调用、实现谁”从而实现多态。而C++符号表中的符号不是以函数名命名的,称为函数名修饰规则,虽然函数名相同,但是函数参数等其他属性不同,取的符号也不同,所以不会产生查询歧义的问题,使得函数可以重载。

qq_46676829的博客 905

wxPython和pycairo练习记录15

像素:是指在由一个数字序列表示的图像中的一个最小单位,称为像素。这里的像素并非我们平时所说的眼睛看到的点,它更像是屏幕上的一个网格,不同的显示设备可能有不同大小的格子。在 Python 中,我们可以方便地通过一些库读取图像的某个像素值。这个例子中,返回的像素值是 RGBA 数值元组。

SmileBasic的博客 416

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

wxPython和pycairo练习记录18

Font.py 中 Font 类居然继承 Spritesheet 类来加载字符对应图片,还和 Sprites 类的功能差不多,总感觉哪里不太对。基本都没法写测试啊,后面待完成的是声音、鼠标键盘输入、碰撞检测、实体和主要显示类:面板、关卡、菜单、暂停画面。Camera.py 摄像机,这里的功能是记录坐标,跟随实体移动坐标。

SmileBasic的博客 396

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

本地化部署 DeepSeek,构建单细胞与空间转录组 AI 分析平台

本地化部署 DeepSeek,构建单细胞与空间转录组 AI 分析平台

weixin_53637133的博客 177

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

AI全栈实战 | 3.9-01 爬虫入门:requests 加 BeautifulSoup 三分钟跑通,但 90% 的人栽在这 4 个“礼貌“问题上

⚠️:本文内容仅用于。请遵守目标站点的服务条款与相关法律法规,不得对目标服务造成负担,不得采集、传播个人隐私数据。技术是中性的,边界在你手里。爬虫的入门技术(requests 发请求 + BeautifulSoup 解析)三分钟就能学会。真正区分"会用爬虫"和"会做爬虫的人"的,是这篇我们跑通"请求→解析→存储"的最小闭环,然后重点把"合规与礼貌"这根弦给你绷上。

源码获取 | 运行部署 | 定制二开修改,如果回复不及时请耐心等待,请见谅。 425

从一段视频到可漫游的 4D 有声场景:思路拆解与最小复现手记

只需一段手机视频,你就能生成可"走进去"的 4D 有声场景:转头时狗叫声方向随之变化,走近时声音更清晰。本文拆解 Video-to-4DAVScene 的核心思路,手把手带你用几十行 Python 搭出最小管线,把视频中的运动物体变成带空间位置的声源,并附上三个真实踩坑的排障经验,代码可直接跑。🎧

helloagent的博客 241

【每天一个 Python 小案例30】Python 基础知识综合小项目:我的工具盒

作为系列收官,本篇把前 29 篇的知识点合成一个能直接用的命令行工具"我的工具盒":计算器(用 ast 解析表达式,不碰 eval)、单位换算与温度转换(一张换算表 + 特例分支)、记账与分类统计(Decimal + JSON 持久化)、以及用"字典当命令表"把菜单和业务逻辑解耦的主循环。文中对比了 eval 的安全隐患与 ast 白名单的做法,解释了 lambda 闭包在字典里的写法与晚绑定陷阱,并在最后给出整个系列的知识地图,把变量、数据结构、控制流、函数、类、异常、文件、标准库八块内容对应到具体篇目。

xinjiyaya的博客 427

yolo 和 deft 算法的区别

你应该是打错了:是,不是 defrat;

曾大强博客 256

二进制木马免杀-Python 分离免杀与 Web 挂马

二进制木马免杀-Python 分离免杀与 Web 挂马

2503_94637398的博客 269

两张表合并之后,行数悄悄多了一倍

pandas merge 行数异常膨胀源于右表键不唯一,导致数据静默复制。实测显示,未聚合的右表(756行)与左表合并后行数增至504行,合计膨胀3.5倍,但无报错。validate 参数仅在检查键唯一性时有效,one_to_one 和 many_to_one 可拦截问题,但需结合 duplicated() 前置检查。正确做法为先按键聚合右表,再合并,避免重复。建议合并前后核对行数、合计,并使用 indicator=True 排查匹配情况,确保数据一致性。

patrickstar231的博客 226

蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级 备考:莫队算法离线区间查询详解

备赛进行时:第十八届蓝桥杯软件赛报名已于 2026-10-08 10:00 开启、12-18 14:00 截止,省赛定在 2027-04-10(C/C++·Python 程序设计 9:00–13:00);中国电子学会 2026 年 12 月软件编程(C/C++ 一级至十级、Python 一级至六级)考级报名 9/23–12/2 16:00、统考 12-12;全国青少年信息素养大赛 2026—2027 赛季算法应用主题赛也已进入复盘练兵窗口。

IT_Scratch的博客 170

我用 200 行代码写了个“代码屎山检测器“,扫完公司的老项目后我沉默了

这个工具不能帮你把屎山铲平,但至少能让你知道自己面对的是多大的山,也能在代码评审时用数据说话——“这个 PR 把圈复杂度从 12 推到了 18,能不能拆一下?毕竟,不能量化的东西,就没法改进。

xixiaoyunya的博客 251

智慧农业实战:育秧车间秧盘计数与苗情分级的Python实现

首先,建立统一的数据结构,保存每盘秧苗的编号、批次、覆盖度、叶色得分和播种天数。A = "壮苗"B = "合格苗"C = "弱苗"@dataclassdays: int。

荆棘鸟智能的博客 118

智叟云集-手机证据抓取系统的工程结构与应用入口

本文系统阐述手机证据抓取系统的工程结构与应用入口,涵盖四大层面:工程目录划分(Android、Python服务、Web页面、测试与构建工具);Android组件通过Manifest声明可启动页面,主界面由MainActivity管理;Python服务通过run.py解析参数并启动FastAPI应用,支持远程访问;浏览器页面采用HTML/CSS/JS分离架构,静态资源通过路径关联,实现动态交互。各模块分工明确,协同构建可运行的采集系统。

2301_77178996的博客 237
上一篇: wxPython和pycairo练习记录6
下一篇: wxPython和pycairo练习记录8
SmileBasic
博客等级 码龄5年 347粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值