首页 > 其他分享 >0238-RLTK-生成大地图

0238-RLTK-生成大地图

时间:2024-08-16 16:27:11浏览次数:8  
标签:RLTK 0238 mut 地图 pos map let world TileType

环境

  • Time 2022-11-29
  • WSL-Ubuntu 22.04
  • RLTK 0.8.7

前言

说明

参考:https://bfnightly.bracketproductions.com/rustbook

目标

基于前一节的内容,生成一张可以让角色移动的大地图。

地板和墙

#[derive(PartialEq, Copy, Clone)]
enum TileType {
    Wall, Floor
}

计算坐标

pub fn index(x: i32, y: i32) -> usize {
    (y as usize * 80) + x as usize
}

生成地图

fn new_map() -> Vec<TileType> {
    let mut map = vec![TileType::Floor; 80 * 50];

    for x in 0..80 {
        map[index(x, 0)] = TileType::Wall;
        map[index(x, 49)] = TileType::Wall;
    }
    for y in 0..50 {
        map[index(0, y)] = TileType::Wall;
        map[index(79, y)] = TileType::Wall;
    }

    let mut rng = rltk::RandomNumberGenerator::new();

    for _i in 0..400 {
        let x = rng.roll_dice(1, 79);
        let y = rng.roll_dice(1, 49);
        let idx = index(x, y);
        if idx != index(40, 25) {
            map[idx] = TileType::Wall;
        }
    }

    map
}

绘制地图

fn draw_map(map: &[TileType], ctx: &mut Rltk) {
    let mut y = 0;
    let mut x = 0;
    for tile in map.iter() {
        match tile {
            TileType::Floor => {
                ctx.set(
                    x,
                    y,
                    RGB::from_f32(0.5, 0.5, 0.5),
                    RGB::from_f32(0., 0., 0.),
                    rltk::to_cp437('.'),
                );
            }
            TileType::Wall => {
                ctx.set(
                    x,
                    y,
                    RGB::from_f32(0.0, 1.0, 0.0),
                    RGB::from_f32(0., 0., 0.),
                    rltk::to_cp437('#'),
                );
            }
        }

        x += 1;
        if x > 79 {
            x = 0;
            y += 1;
        }
    }
}

墙壁碰撞

fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
    let mut positions = ecs.write_storage::<Position>();
    let mut players = ecs.write_storage::<Player>();
    let map = ecs.fetch::<Vec<TileType>>();

    for (_player, pos) in (&mut players, &mut positions).join() {
        let destination_idx = xy_idx(pos.x + delta_x, pos.y + delta_y);
        if map[destination_idx] != TileType::Wall {
            pos.x = min(79 , max(0, pos.x + delta_x));
            pos.y = min(49, max(0, pos.y + delta_y));
        }
    }
}

GameState

impl GameState for State {
    fn tick(&mut self, ctx: &mut Rltk) {
        ctx.cls();

        player_input(self, ctx);
        self.run_systems();

        let map = self.world.fetch::<Vec<TileType>>();
        draw_map(&map, ctx);

        let positions = self.world.read_storage::<Position>();
        let renderables = self.world.read_storage::<Renderable>();
        for (pos, render) in (&positions, &renderables).join() {
            ctx.set(pos.x, pos.y, render.fg, render.bg, render.glyph);
        }
    }
}

main

fn main() -> rltk::BError {
    let context = rltk::RltkBuilder::simple80x50()
        .with_title("冒险游戏")
        .build()?;

    let mut state = State {
        world: World::new(),
    };
    state.world.register::<Position>();
    state.world.register::<Renderable>();
    state.world.register::<LeftWalker>();
    state.world.register::<Player>();

    state.world.insert(new_map());

    state
        .world
        .create_entity()
        .with(Position { x: 40, y: 25 })
        .with(Renderable {
            glyph: rltk::to_cp437('@'),
            fg: RGB::named(rltk::YELLOW),
            bg: RGB::named(rltk::BLACK),
        })
        .with(Player {})
        .build();

    rltk::main_loop(context, state)
}

效果

控制角色移动

总结

生成一张大地图,角色可以在除了墙的地方行走。

附录

标签:RLTK,0238,mut,地图,pos,map,let,world,TileType
From: https://www.cnblogs.com/jiangbo4444/p/18363133

相关文章

  • 0239-RLTK-分割不同文件
    环境Time2022-11-30WSL-Ubuntu22.04RLTK0.8.7前言说明参考:https://bfnightly.bracketproductions.com/rustbook目标基于前一节的内容,随着main.rs文件中的内容越来越多,将其进行分割。comp.rsuserltk::RGB;usespecs::prelude::*;usespecs_derive::Component;......
  • 0240-RLTK-生成小房间
    环境Time2022-11-30WSL-Ubuntu22.04RLTK0.8.7前言说明参考:https://bfnightly.bracketproductions.com/rustbook目标基于前一节的内容,生成两个小房间,只修改map.rs文件。生成房间函数fnapply_room_to_map(room:&Rect,map:&mut[TileType]){foryinroom......
  • P10238 [yLCPC2024] F. PANDORA PARADOXXX 题解
    题目传送门前置知识树链剖分|树的直径|最近公共祖先|并查集解法正着删边不太可做,考虑离线下来反着加边。一个显而易见的结论:设点集\(A\)的直径的两个端点为\(u_{1},v_{1}\),另一个点集\(B\)的直径的两个端点为\(u_{2},v_{2}\),则\(A\bigcupB\)的直径端点一定是......
  • 使用Python创建省份城市地图选择器
    在这篇博客中,我们将探讨如何使用Python创建一个简单而实用的省份城市地图选择器。这个项目不仅能帮助我们学习Python的基础知识,还能让我们了解如何处理JSON数据和集成网页浏览器到桌面应用程序中。C:\pythoncode\new\geographicgooglemap.py全部代码importwximportwx.......
  • 高德地图SDK Android版开发 5 地图交互操作
    高德地图SDKAndroid版开发5地图交互操作前言控件控件介绍接口UiSettingsAMapOptions示例代码Logo指南针比例尺缩放按钮效果图地图手势地图手势方法说明地图手势开关指定屏幕中心点的手势操作地图手势事件地图点击事件监听接口地图长按事件监听接口地图触摸事件监......
  • 百度地图SDK Android版开发 5 地图交互操作
    百度地图SDKAndroid版开发5地图交互操作前言控件控件介绍接口MapViewBaiduMapUiSettingsLogoPosition示例代码Logo指南针比例尺缩放按钮地图上控件边距效果图地图手势地图手势方法说明地图手势开关接口地图手势事件地图单击事件监听接口地图双击事件监听接口地图长......
  • 如何为微信小程序添加地图和位置服务
    为微信小程序添加地图和位置服务可以通过使用微信提供的地图组件和位置API实现。以下是详细步骤和示例代码:创建一个新的微信小程序项目:使用微信开发者工具创建一个新的微信小程序项目。在创建项目时,可以选择"位置"和"地图"权限,以便后续使用位置和地图服务。在小程序......
  • uni-app使用天地图
    原因:由于主流地图(百度,高德,腾讯)商用收费属实昂贵,不得已很多人开始转战天地图。  方案:天地图想要在uniapp项目中正常使用目前的方案有两种1.通过web-view将html天地图嵌入项目中  优点:可以同时兼容微信小程序和APP缺点:地图嵌入后数据交互繁琐,小程序兼容了,但是兼的不是很......
  • React 高德地图 进京证 路线规划 问题小记
    一、加载问题用高德地图做了个进京证路线规划的功能,官网也是有React代码示例。但是吧,这个Demo有问题,地图是能加载成功,但是其他功能再用map这个变量肯定不行,果不其然是null,处理也简单,把公共变量都管理起来就行了。const[map,setMap]=useState(null);const[AMap,setAMa......
  • 0234-RLTK-创建主程序窗口
    环境Time2022-11-29WSL-Ubuntu22.04RLTK0.8.7前言说明参考:https://bfnightly.bracketproductions.com/rustbook/chapter_1.html目标RLTK表示RoguelikeToolkit,随机游戏工具包,使用这个包创建一个主窗口。Cargo.toml[package]edition="2021"name="game"vers......