如何复制/克隆一个既不派生又不派生的结构?

2024-05-26

我正在尝试用 Piston 进行一些游戏编程,但我正在努力解决opengl_graphics::Texture,因为它没有导出Copy or Clone.

extern crate piston_window;
extern crate piston;
extern crate graphics;
extern crate opengl_graphics;

use opengl_graphics::Texture as Tex;
use piston_window::*;
use std::path::Path;
use opengl_graphics::GlGraphics;

#[derive(PartialEq)]
enum ObjectType {
    Blocking,
    Passing,
}
struct Object {
    sprite: Tex,
    obj_type: ObjectType,
    position: Position,
}
struct Game {
    gl: GlGraphics,
    images: Vec<Object>,
    player: Player,
}
struct Player {
    sprite: Tex,
    position: Position,
}
struct Position {
    x: i32,
    y: i32,
}

impl Game {
    fn render(&mut self, args: &RenderArgs) {

        let iter = self.images.iter();
        let player = &self.player;
        self.gl.draw(args.viewport(), |c, g| {

            clear([1.0, 1.0, 1.0, 1.0], g);

            for img in iter {
                let pos = img.get_position();
                let transform = c.transform.trans(((pos.x * 64)) as f64, ((pos.y * 64)) as f64);
                image(img.get_sprite(), transform, g);
            }
            image(player.get_sprite(),
                  c.transform.trans((player.get_position().x * 64) as f64,
                                    (player.get_position().y * 64) as f64),
                  g);
        });
    }


    fn update(&mut self, args: &UpdateArgs) {}
}

主游戏循环:

fn main() {
    let (width, height) = (64*10, 64*10);
    let opengl = OpenGL::V3_2;
    let mut window: PistonWindow =
        WindowSettings::new("piston", (width, height))
        .exit_on_esc(true)
        .opengl(opengl)
        .build()
        .unwrap();
    window.hide();
    println!("Loading...");
    let mut player = Player { sprite: Tex::from_path(&Path::new(
                            "./assets/player_n.png")).unwrap(),
                            position: Position { x: 3, y: 3 },
    };

    let mut game = Game {
        gl: GlGraphics::new(opengl),
        images: Vec::new(),
        player: player,
    };

    for i in 0..10 {
        for j in 0..10 {
            if i == 0 || i == 9 || j == 0 || j == 9 {
                let obj = Object { sprite: Tex::from_path(&Path::new(
                        "./assets/wall.png")).unwrap(),                                                 
                    obj_type: ObjectType::Blocking,
                        position: Position { x: i, y: j },
                };
                game.images.push(obj);

            } else {
                let obj = Object { sprite: Tex::from_path(&Path::new(
                        "./assets/floor.png")).unwrap(),                                                
                    obj_type: ObjectType::Passing,
                        position: Position { x: i, y: j },
                };
                game.images.push(obj);
            }
        }
    }
    window.show();
    while let Some(e) = window.next() {

        if let Some(Button::Keyboard(key)) = e.press_args() {
            let mut pos = game.player.position.clone();
            let mut spr: Option<Tex> = None;          
            match key {
                Key::Up => { pos.y -= 1; spr = Some(Tex::from_path(&Path::new(
                        "./assets/player_n.png")).unwrap()); },
                Key::Down => { pos.y += 1; spr = Some(Tex::from_path(&Path::new(
                        "./assets/player_s.png")).unwrap()); },
                Key::Left => { pos.x -= 1; spr = Some(Tex::from_path(&Path::new(
                        "./assets/player_w.png")).unwrap()); },              
                Key::Right => { pos.x += 1; spr = Some(Tex::from_path(&Path::new(
                        "./assets/player_e.png")).unwrap()); },
                _ => (),
            }
            for elem in game.images.iter() {
                if pos.x == elem.position.x && pos.y == elem.position.y && elem.obj_type == ObjectType::Passing {
                    game.player.position = pos;

                    game.player.sprite = spr.clone().unwrap();

                }
            }
        }        
        if let Some(r) = e.render_args() {
            game.render(&r);       
        }
        if let Some(u) = e.update_args() {
            game.update(&u); 
        }
    }
}

产生错误:

error: no method named `clone` found for type `std::option::Option<opengl_graphics::Texture>` in the current scope
   --> src/main.rs:159:46
159 |                     game.player.sprite = spr.clone().unwrap();
    |                                              ^^^^^
    |
    = note: the method `clone` exists but the following trait bounds were not satisfied: `opengl_graphics::Texture : std::clone::Clone`

我明白为什么会出现此错误,因为opengl_graphics::Texture不得出Copy我无法克隆Option<opengl_texture>。有什么解决方法吗?

我尝试乱搞参考资料,但没有成功。


如何复制/克隆一个既不派生又不派生的结构?

你不知道。您唯一能做的就是对其进行某种参考。


在这种情况下,图书馆选择不实施是一件非常好的事情Clone or Copy。如果您能够克隆该结构,您将频繁且不必要地分配大量内存。相反,该库迫使您考虑何时分配该内存。解决方案之一是在应用程序启动时加载所有纹理并引用它们:

更改结构以保存引用:

#[derive(PartialEq)]
enum ObjectType {
    Blocking,
    Passing,
}

struct Object<'a> {
    sprite: &'a Tex,
    obj_type: ObjectType,
    position: Position,
}

struct Game<'a> {
    gl: GlGraphics,
    images: Vec<Object<'a>>,
    player: Player<'a>,
}

struct Player<'a> {
    sprite: &'a Tex,
    position: Position,
}

#[derive(Copy, Clone, PartialEq)]
struct Position {
    x: i32,
    y: i32,
}

struct Textures {
    player_n: Tex,
    player_s: Tex,
    player_e: Tex,
    player_w: Tex,
    wall: Tex,
    floor: Tex,
}

尽早加载纹理main。请注意,没有必要使用Path明确地,因为它需要AsRef<Path>:

let textures = Textures {
    player_n: Tex::from_path("./assets/player_n.png").unwrap(),
    player_s: Tex::from_path("./assets/player_s.png").unwrap(),
    player_e: Tex::from_path("./assets/player_e.png").unwrap(),
    player_w: Tex::from_path("./assets/player_w.png").unwrap(),
    wall: Tex::from_path("./assets/wall.png").unwrap(),
    floor: Tex::from_path("./assets/floor.png").unwrap()
};

然后传递对这些纹理的引用:

match key {
    Key::Up => {
        pos.y -= 1;
        spr = Some(&textures.player_n)
    }
    Key::Down => {
        pos.y += 1;
        spr = Some(&textures.player_s)
    }
    Key::Left => {
        pos.x -= 1;
        spr = Some(&textures.player_w)
    }
    Key::Right => {
        pos.x += 1;
        spr = Some(&textures.player_e)
    }
    _ => (),
}
for elem in game.images.iter() {
    if pos == elem.position && elem.obj_type == ObjectType::Passing {
        game.player.position = pos;

        if let Some(spr) = spr {
            game.player.sprite = spr;
        }
    }
}

请注意,这还合并了可能发生错误的位置。不再有一个unwrap在循环的内部。

我无法让您的代码完成编译,因为代码不完整,但这应该有助于开始:

error: no method named `render` found for type `Game<'_>` in the current scope
   --> src/main.rs:122:18
    |
122 |             game.render(&r);
    |                  ^^^^^^
    |
    = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `render`, perhaps you need to implement it:
    = help: candidate #1: `piston_window::RenderEvent`

error: no method named `update` found for type `Game<'_>` in the current scope
   --> src/main.rs:125:18
    |
125 |             game.update(&u);
    |                  ^^^^^^
    |
    = help: items from traits can only be used if the trait is implemented and in scope; the following traits define an item `update`, perhaps you need to implement one of them:
    = help: candidate #1: `piston_window::UpdateEvent`
    = help: candidate #2: `piston_window::<unnamed>::UpdateTexture`
    = help: candidate #3: `deflate::checksum::RollingChecksum`
    = help: candidate #4: `cocoa::appkit::NSOpenGLContext`
    = help: candidate #5: `cocoa::appkit::NSOpenGLContext`

在某些情况下,您可以将类型包装在Rc or Arc并克隆它。克隆一个Rc/Arc只增加一个引用计数器,无论实现如何Clone对于底层类型(或缺乏这样的实现)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何复制/克隆一个既不派生又不派生的结构? 的相关文章

随机推荐

  • 匿名 IComparer 实现

    是否可以定义 IComparer 的匿名实现 我相信 Java 允许内联定义匿名类 C 可以吗 看着这段代码我想定义一个自定义IComparer inline public static IOrderedEnumerable
  • python subprocess proc.stderr.read() 引入额外的行?

    我想运行一些命令并抓取输出到 stderr 的任何内容 我有两个版本的函数可以执行此操作 版本 1 def Getstatusoutput cmd Return status output of executing cmd in a she
  • 将 Null 与 MySQL 触发器中的另一个值进行比较

    所以这是我的问题 我在更新表行时比较新值和旧值 但新值或旧值有时会为空 所以下面的代码不起作用 我可以解决这个问题吗 谢谢 BEFORE UPDATE ON mytable FOR EACH ROW BEGIN IF OLD assigne
  • 将 XMM 寄存器压入堆栈

    有没有办法将打包双字整数从 XMM 寄存器推送到堆栈 然后在需要时将其弹出 理想情况下 我正在寻找通用寄存器的 PUSH 或 POP 之类的东西 我已经检查了英特尔手册 但我要么错过了命令 要么没有 或者我是否必须将值解压到通用寄存器然后推
  • 布局中的模型破坏了其他页面

    由于缺乏 MVC4 经验 我有一个设计缺陷 问题是我的布局中有一个模型 model BasicFinanceUI Models LoginModel Content Site css rel stylesheet type text css
  • 随机字体颜色

    我需要用 2 或 3 种随机颜色为文本着色 我如何在 PHP 或 JavaScript 中执行此操作 color str pad sprintf x x x rand 0 255 rand 0 255 rand 0 255 6 rand 0
  • 使用 Gradle 在多个 Android 应用程序之间共享 Android 库

    我有 Android 应用程序 A 和 B 我想将每个应用程序中的重复代码提取到共享库 L 中 如何使用 Gradle 执行此操作 我之前见过这个问题的一些排列 但答案很少 最接近 最好的已问问题是这个 多个 Android 应用程序依赖于
  • Angular2:类型错误:无法读取未定义的属性“Symbol(Symbol.iterator)”

    我是可观察对象的新手 正在尝试 Christoph Burgdorf 的基本自动完成变体Angular2 博客中的可观察量 http blog thoughtram io angular 2016 01 07 taking advantag
  • CakePHP 中的 hasMan 简化为 hasOne

    基本上我在 CakePHP 中有以下模型 User id username Photo id user id path 我已经建立了以下关系 用户有很多照片 在一个屏幕上 我想列出用户 并在每个用户旁边显示随机照片 我尝试建立以下关系 用户
  • 如何将字符串列表转换为正确的 Python 类型?

    给定一个 python 字符串列表 如何自动将它们转换为正确的类型 意思是 如果我有 hello 3 3 64 1 我希望将其转换为列表 hello 3 3 64 1 其中第一个元素是字符串 第二个元素是 int 第三个元素是 float
  • 如何发出HTTP请求将文件从reactjs上传到googledrive?

    我对文档有点困惑 我做了我的研究 资源很少 也许有人可以帮助我 我正在使用 CRNA create react app 我有一个按钮 可以使用 URI 将文件上传到 Google Drive 我已经有了 API 密钥 客户端 ID 启用 A
  • 使用 Windows 锁定屏幕后删除 Kerberos 缓存票证

    无论如何 有没有办法阻止 Kerberos 缓存的票证在 Windows 进入锁定屏幕后被删除 首次登录 Windows 时 klist exe 显示 2 个缓存票证 但是 发生 Windows 锁屏事件后 klist exe 显示 0 个
  • C# Winform 表单中的表单

    我想打开一个表单的多个实例并将其显示在另一种表单或另一种表单的面板中 怎么做 如果您不使用 MDI 您仍然可以将一个窗体添加到另一个窗体或窗体上的面板 public Form1 InitializeComponent Form2 embed
  • Python 字典不按顺序排列

    我创建了一个字母表字典 其值从0开始 并根据单词文件增加一定的量 我对最初的字典进行了硬编码 我希望它保持按字母顺序排列 但事实并非如此 我希望它按字母顺序返回字典 基本上与初始字典保持相同 我怎样才能保持秩序 from wordData
  • NodeJS“加密”哈希似乎产生与 Crypto-JS javascript 库不同的输出

    我正在使用 NodeJS 的捆绑包crypto http nodejs org api crypto html crypto class hash服务器端 SHA256 哈希模块 在客户端 我使用一个名为的 javascript 库Cryp
  • 如何强制重装iOS模拟器?

    我想下载模拟器组件 Xcode 6 2 但在下载过程中我的互联网连接丢失了 Xcode 仍然显示我已经安装了 7 1 模拟器 你知道如何强制重装iOS模拟器吗 我已完成以下步骤 从 Library Caches com apple dt X
  • 无法在 routerOnActivate 上获取查询参数

    我在尝试使用新的路线库获取查询参数时遇到问题 VERSION2 0 0 rc 1 Problem routerOnActivate curr RouteSegment prev RouteSegment currTree RouteTree
  • 使用 pybind11 修改 std::array 的默认值

    我的目标是修改在中声明的数组C struct并赋予默认值 我读过了this https pybind11 readthedocs io en stable advanced cast stl html making opaque types
  • 如何避免在 ASP.NET 代码隐藏中编写混乱的 JavaScript?

    我想知道在 ASP NET 中使用 Javascript 的最佳实践是什么 我不知道这是否是最佳实践 但我在代码隐藏中添加了 javascript 客户端事件 它工作正常 但这是最佳实践吗 例如 我有一个单选按钮控件 并在 Page Ini
  • 如何复制/克隆一个既不派生又不派生的结构?

    我正在尝试用 Piston 进行一些游戏编程 但我正在努力解决opengl graphics Texture 因为它没有导出Copy or Clone extern crate piston window extern crate pist