使用Jetpack Compose构建Flappy Musketeer街机游戏

news2024/9/20 16:57:20

使用Jetpack Compose构建Flappy Musketeer街机游戏

一步一步创建沉浸式移动游戏的指南

引言

Flappy Musketeer不仅是又一个移动游戏;它将令人上瘾的“轻点飞行”游戏玩法和引人入胜的视觉效果融合在一起,吸引玩家进入埃隆·马斯克(Elon Musk)的非凡事业,包括SpaceX和Twitter(X)。此外,玩家可以通过选择各种主题和配色方案来个性化他们的游戏体验。

在本文中,我们将使用Jetpack Compose从头开始构建Flappy Musketeer。我们将剖析代码、逻辑和设计决策,让您了解创造沉浸式安卓游戏体验的过程。

App实现架构

源代码概述图表
Game Source Code Overview Diagram

使用Jetpack Compose 设置主题

在Flappy Musketeer中,创建正确的氛围和视觉美学对玩家的体验至关重要。让我们更详细地看看如何实现这一点。

  1. AppTheme Composable

我们的主题系统的核心在于AppTheme Composable。这个Composable负责将选定的配色方案应用到整个游戏的用户界面。以下是它的外观 -

@Composable
fun AppTheme(
    colorScheme: ColorScheme = twitter,
    content: @Composable () -> Unit
) {
    val view = LocalView.current
    if (!view.isInEditMode) {
        SideEffect {
            val window = (view.context as Activity).window
            window.statusBarColor = colorScheme.primary.toArgb()
            window.navigationBarColor = colorScheme.primary.toArgb()
        }
    }

    MaterialTheme(
        colorScheme = colorScheme,
        content = content
    )
}

AppTheme Composable负责配置配色方案,并将其应用于Android设备的状态栏和导航栏。这确保了游戏中始终具有一致的视觉体验。

  1. 自定义配色方案

Flappy Musketeer为玩家提供了各种主题和配色方案可供选择。以下是一些可用选项的概览
Game Theme Colors

Space.X.Mars - 受火星的锈色地形启发。
Twitter.Doge - 一个玩味十足的主题,以Dogecoin吉祥物为特色。
Twitter.White - 白色配色方案的清洁和极简设计。
Space.X.Moon - 受月球宁静美丽的黑暗主题启发。

这些主题在代码中被定义为ColorScheme对象,可以轻松自定义并应用于游戏用户界面的不同部分。

val spaceX = darkColorScheme(
    primary = spacePurple,
    secondary = Color.Black,
    tertiary = Color.Black
)

val twitter = darkColorScheme(
    primary = earthYellow,
    secondary = twitterBlue,
    tertiary = Color.Black
)

通过提供各种主题,Flappy Musketeer为玩家提供了个性化的游戏体验。

  1. 主题背景

除了配色方案,Flappy Musketeer还提供了与所选配色方案相匹配的各种背景。这些背景为游戏环境增添了深度和沉浸感。我们使用GameBackground枚举类来维护背景集合。这些背景图像根据所选主题动态加载,确保游戏的视觉效果与玩家的偏好相一致。

enum class GameBackground(val url: String) {
    TWITTER_DOGE("https://source.unsplash.com/qIRJeKdieKA"),
    SPACE_X("https://source.unsplash.com/ln5drpv_ImI"),
    SPACE_X_MOON("https://source.unsplash.com/Na0BbqKbfAo"),
    SPACE_X_MARS("https://source.unsplash.com/-_5dCixJ6FI")
}
  1. 在游戏中切换主题

为了使主题选择过程无缝进行,Flappy Musketeer提供了一个getGameTheme函数,该函数以主题名称作为输入,并返回相应的ColorScheme。以下是其工作原理 -

fun getGameTheme(gameId: String?): ColorScheme {
    return when (gameId) {
        GameBackground.SPACE_X.name -> spaceX
        GameBackground.TWITTER.name -> twitter
        // ... (other theme mappings)
        else -> twitter
    }
}

这个函数允许游戏根据菜单中的游戏选项选择来切换主题。

通过Flappy Musketeer导航

现在我们已经介绍了使用Jetpack Compose进行主题设置的基础知识,让我们将重点转向游戏的导航。Flappy Musketeer利用Navigation组件来在不同的屏幕和游戏状态之间实现无缝切换。

  1. App Composable
    导航系统的核心是App composable。这个composable使用Jetpack Compose的Navigation组件来设置游戏的导航。以下是它的样子 -
@Composable
fun App() {
    val navController = rememberNavController()
    NavHost(navController = navController, startDestination = AppRoutes.MENU.name) {
        composable(AppRoutes.MENU.name) {
            AppTheme(colorScheme = menuTheme) {
                GameMenu(navController)
            }
        }
        composable("${AppRoutes.GAME.name}/{gameId}") {
            val gameId = it.arguments?.getString("gameId")
            val gameTheme = getGameTheme(gameId)

            AppTheme(colorScheme = gameTheme) {
                GameScreen(navController, gameId)
            }
        }

        composable(AppRoutes.GAME_OVER.name) {
            XLottie(navController)
        }
    }
}

这段代码设置了导航图,定义了游戏的流程。让我们来详细解析一下:

App composable 初始化了NavController,用于管理游戏内的导航。
我们将MENU屏幕设置为初始目标。
在NavHost中,我们为每个屏幕定义了可组合函数,例如游戏菜单和游戏界面。
我们使用AppTheme为每个屏幕应用相应的主题,以保持视觉一致性。

  1. 导航目的地
    Navigation Destinations
    菜单屏幕(AppRoutes.MENU.name)- 当玩家第一次打开游戏时,他们会进入这个屏幕。AppTheme可组合函数设置了菜单主题,为游戏的主菜单创建了一个统一的外观。玩家可以在这里选择游戏。

游戏屏幕(${AppRoutes.GAME.name}/{gameId})- 游戏屏幕根据所选的游戏动态调整其主题。使用getGameTheme函数,我们获取相应的配色方案,并使用AppTheme应用它。这确保每个游戏的主题与其环境相匹配,无论是Twitter.Doge还是Space.X.Mars。

游戏结束屏幕(AppRoutes.GAME_OVER.name)- 当游戏结束时,显示此屏幕,并带有一个Twitter X Lottie动画。当玩家的游戏结束时,导航系统会无缝地过渡到这个屏幕。

通过这种导航设置,玩家可以轻松浏览Flappy Musketeer的不同部分,从选择游戏到游戏过程中,再到游戏结束屏幕的体验。

创建Game Menu

游戏菜单通常是玩家的第一个互动点,为整个游戏体验设定了基调。在Flappy Musketeer中,游戏菜单被设计成视觉上引人入胜且用户友好的。让我们更详细地看一下它是如何实现的

  1. GameMenu可组合函数
    GameMenu可组合函数是进入Flappy Musketeer的入口点。它为玩家提供了访问各种游戏主题和重要链接的方式。以下是定义GameMenu的代码片段 -
    Game Menu
@Composable
fun GameMenu(navController: NavController) {
    val uriHandler = LocalUriHandler.current

    // ... (Theme setup)

    Column(modifier = Modifier.fillMaxSize()) {
        // ... (Top bar styling)

        Column(
            modifier = Modifier
                .wrapContentHeight()
                .fillMaxWidth()
                .background(Color(0xFF0E2954)),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            // ... (Logo and app name)

            Spacer(modifier = Modifier.height(10.dp))

            Row {
                // ... (About App button)

                Spacer(modifier = Modifier.width(12.dp))

                // ... (Creator button)
            }
        }

        Row(
            modifier = Modifier
                .fillMaxSize()
                .horizontalScroll(rememberScrollState(), enabled = true)
                .background(
                    brush = Brush.verticalGradient(
                        listOf(
                            Color(0xFF0E2954),
                            Color(0xFF1F6E8C)
                        )
                    )
                ),
            horizontalArrangement = Arrangement.Center,
            verticalAlignment = Alignment.CenterVertically
        ) {
            Spacer(modifier = Modifier.width(30.dp))

            GameBackground.values().forEach {
                MenuItem(
                    navController,
                    backgroundUrl = it.url,
                    name = it.name.replace("_", ".").uppercase(),
                    originalName = it.name
                )
                Spacer(modifier = Modifier.width(30.dp))
            }
        }
    }
}
  • 游戏的标志以IconButton的形式显示,当点击时会打开一个链接。这为菜单屏幕增添了一丝互动性。
  • 应用程序名称使用buildAnnotatedString进行样式设置,允许自定义字体粗细和样式。
  • 菜单以水平滚动行的形式实现,允许玩家通过滑动浏览不同的主题。每个主题都表示为一个MenuItem可组合函数,具有其背景图像和名称。
  1. MenuItem Composable
@Composable
fun MenuItem(
    navController: NavController,
    backgroundUrl: String,
    name: String,
    originalName: String
) {
    // ... (Menu item content)
}

这个可组合函数负责显示主题的背景图像和名称。当单击时,它会根据所选主题将玩家导航到相应的游戏屏幕。

主屏幕逻辑

GameScreen可组合函数是Flappy Musketeer游戏中负责管理游戏逻辑的核心组件。这个代码文件定义了游戏在游戏过程中的行为,包括处理用户输入、更新游戏状态和渲染游戏元素。

让我们逐步分解GameScreen可组合函数,并用相关的代码片段解释每部分代码

  1. 状态初始化
// 初始化游戏状态和得分
var gameState by remember { mutableStateOf(GameState.NOT_STARTED) }
var score by remember { mutableLongStateOf(0L) }
var lastScore by remember { mutableLongStateOf(preferencesManager.getData("last_score", 0L)) }
var bestScore by remember { mutableLongStateOf(preferencesManager.getData("best_score", 0L)) }
var birdOffset by remember { mutableStateOf(0.dp) }
var birdRect by remember { mutableStateOf(Rect(0f, 0f, 64.dp.value, 64.dp.value)) }

在这一部分,我们初始化各种游戏状态变量,如gameState、score、lastScore、bestScore、birdOffset和birdRect。这些变量用于跟踪游戏的进展和鸟的位置。

  1. 管道(障碍物)尺寸初始化
    Pipe Dimensions
var pipeDimensions by remember {
    mutableStateOf(Triple(0.1f, 0.4f, 0.5f))
}

在这里,我们将pipeDimensions初始化为Triple,以存储顶部、间隙和底部管道的权重。这些权重确定了管道的相对大小。

管道(障碍物)尺寸初始化
通过remember创建一个 mutableStateOf,将 pipeDimensions 初始化为 Triple(0.1f, 0.4f, 0.5f)。这个 Triple 存储了顶部管道、间隙和底部管道的权重,这些权重决定了管道的相对大小。

  1. 更新分数回调
val updateScoreCallback: (Long) -> Unit = {
    score += it
}

updateScoreCallback 是一个回调函数,用于在必要时更新游戏的分数。

  1. 小鸟下落动画
    Bird Falling
LaunchedEffect(key1 = birdOffset, gameState) {
    while (gameState == GameState.PLAYING) {
        delay(16)
        birdOffset += 4.dp
    }
}

在这部分中,我们使用 LaunchedEffect 来持续更新 birdOffset,并在游戏处于 PLAYING 状态时模拟小鸟的下落。

  1. 更新小鸟和管道的矩形区域
val updateBirdRect: (birdRect: Rect) -> Unit = {
    birdRect = it
    pipeDimensions = getPipeDimensions(it, screenHeight)
}

这些回调函数负责更新小鸟和管道的矩形区域。这些矩形区域对于检测小鸟和管道之间的碰撞非常重要。

  1. 碰撞检测
    Collision Detection
val updatePipeRect: (pipeRect: Rect) -> Unit = {
    if (!it.intersect(birdRect).isEmpty) {
        // 处理与管道的碰撞
        // ...
    }
}

这个回调函数处理小鸟和管道之间的碰撞检测。当检测到碰撞时,游戏状态转变为 COMPLETED,并更新最高分和最近分数。此外,我们还导航到游戏结束界面(详见导航部分)。

  1. 点击手势处理
Box(
    modifier = Modifier
        .fillMaxSize()
        .pointerInput(Unit) {
            detectTapGestures(
                onTap = {
                    if (gameState == GameState.PLAYING) {
                        // 处理小鸟跳跃
                        coroutineScope.launch {
                            var offsetChange = 80.dp
                            while (offsetChange > 0.dp) {
                                birdOffset -= 2.dp
                                delay(2L)
                                offsetChange -= 2.dp
                            }
                        }
                    }
                }
            )
        }
)

在这里,我们设置了点击手势处理。当玩家在游戏过程中点击屏幕时,更新小鸟的位置以模拟跳跃。

  1. 游戏布局
  2. Box Composable —
Box(
    modifier = Modifier.fillMaxSize()
) {
    // ...
}

游戏布局被封装在一个 Box composable 中,允许在其上方放置多个组件。

  1. 背景 —
Background()

Background composable 渲染游戏的背景,并根据选择的主题设置适当的背景图像。

  1. 管道 —
Pipes(
    updatePipeRect = updatePipeRect,
    updateScoreCallback = updateScoreCallback,
    gameState = gameState,
    pipeDimensions = pipeDimensions.copy()
)

Pipes composable 管理管道的生成和移动。它处理与小鸟的碰撞检测并更新分数。

  1. 游戏状态处理 —
when (gameState) {
    // ...
}

这部分使用 when 表达式处理不同的游戏状态 —

GameState.PLAYING — 在游戏进行中显示小鸟、分数和暂停按钮。点击暂停按钮触发暂停回调。
GameState.NOT_STARTED, GameState.COMPLETED — 显示“Play”按钮以开始或重新开始游戏。如果有可用的最近分数和最高分,则显示上次分数和最高分。
GameState.PAUSE — 显示“Play”按钮以恢复游戏。

  1. 小鸟 —
Bird(birdOffset, updateBirdRect)

Bird composable 在屏幕上渲染小鸟角色。birdOffset 决定了小鸟的垂直位置,模拟其移动。

  1. Play 按钮 —
Play(onPlayCallback)
  • Play composable 显示“Play”按钮,允许玩家在点击时开始或恢复游戏。按下按钮时触发 onPlayCallback。
  1. 地面 —
Ground("Flappy Score", score, enablePause = true, onPauseCallback)

Ground composable 显示游戏的分数,并在 enablePause 设置为 true 时包含一个可选的暂停按钮。按下暂停按钮时触发 onPauseCallback

@Composable
fun Bird(birdOffset: Dp, updateBirdRect: (Rect) -> Unit) {

    val bird = when (MaterialTheme.colorScheme.primary) {
        spaceX.primary, spaceXMars.primary, spaceXMoon.primary -> {
            R.drawable.space
        }

        twitterDoge.primary -> {
            R.drawable.doge
        }

        else -> R.drawable.bird
    }

    bird.let {
        Box(
            modifier = Modifier
                .size(64.dp)
                .offset(y = birdOffset)
                .padding(5.dp)
                .onGloballyPositioned {
                    updateBirdRect(it.boundsInRoot())
                }
        ) {
            when (MaterialTheme.colorScheme.primary) {
                spaceX.primary, spaceXMoon.primary, spaceXMars.primary -> {
                    Image(painterResource(id = it), contentDescription = "rocket")
                }

                else -> {
                    if (MaterialTheme.colorScheme.primary == twitterDoge.primary) {
                        Image(painterResource(id = it), contentDescription = "doge rocket")
                    } else {
                        Icon(
                            painterResource(id = it),
                            tint = MaterialTheme.colorScheme.secondary,
                            contentDescription = "bird"
                        )
                    }
                }
            }
        }
    }
}

深入了解每个组件

在本节中,我们将深入探讨《Flappy Musketeer》游戏的游戏布局。我们将探索构成游戏界面的以下关键组件:

1. 小鸟( Bird)

@Composable
fun Bird(birdOffset: Dp, updateBirdRect: (Rect) -> Unit) {

    val bird = when (MaterialTheme.colorScheme.primary) {
        spaceX.primary, spaceXMars.primary, spaceXMoon.primary -> {
            R.drawable.space
        }

        twitterDoge.primary -> {
            R.drawable.doge
        }

        else -> R.drawable.bird
    }

    bird.let {
        Box(
            modifier = Modifier
                .size(64.dp)
                .offset(y = birdOffset)
                .padding(5.dp)
                .onGloballyPositioned {
                    updateBirdRect(it.boundsInRoot())
                }
        ) {
            when (MaterialTheme.colorScheme.primary) {
                spaceX.primary, spaceXMoon.primary, spaceXMars.primary -> {
                    Image(painterResource(id = it), contentDescription = "rocket")
                }

                else -> {
                    if (MaterialTheme.colorScheme.primary == twitterDoge.primary) {
                        Image(painterResource(id = it), contentDescription = "doge rocket")
                    } else {
                        Icon(
                            painterResource(id = it),
                            tint = MaterialTheme.colorScheme.secondary,
                            contentDescription = "bird"
                        )
                    }
                }
            }
        }
    }
}

在《Flappy Musketeer》游戏中,Bird 组合负责渲染玩家控制的角色,通常称为“小鸟”,玩家通过控制小鸟穿越管道。让我们详细了解这个组合的关键方面:

  • birdOffset - 这个参数表示小鸟的垂直偏移量,表示其在屏幕上的位置。它根据玩家的输入和重力进行更新,模拟小鸟的飞翔和下落。
  • updateBirdRect - 一个回调函数,用于更新小鸟的位置和尺寸,以进行碰撞检测。

在composable中

  1. 根据当前主题的主色调,将 bird 变量分配给图像资源。游戏根据所选主题提供不同的小鸟图像,例如“spaceX”、“spaceXMars”、“spaceXMoon”或“twitterDoge”。
  2. 使用 Box 组合来容纳小鸟图像。它有一个固定大小为64x64密度无关像素(dp),并根据 birdOffset 在垂直方向上定位。
  3. 使用 onGloballyPositioned 修饰符来检测小鸟在屏幕上的位置,并使用其边界调用 updateBirdRect 回调函数。

Box 的内容根据主题而变化

  • 对于太空主题(spaceX、spaceXMars、spaceXMoon),它显示一个带有火箭图像的 Image,代表小鸟。
  • 对于“twitterDoge”主题,它显示一个带有 doge 主题的火箭图像的 Image。
  • 对于其他主题,它显示一个带有小鸟图像的图标,图标的颜色会根据当前主题的次要颜色进行着色。

这个组合允许根据游戏的主题以不同的方式呈现小鸟角色,为玩家提供与所选主题相匹配的视觉体验。

2. 管道(障碍物)
Twitter Pink

A)主要组合

管道组件负责在游戏中渲染和管理玩家必须穿过的管道。它还处理生成和移动管道的逻辑,这些都是基于游戏事件的。

关键点

updatePipeRect - 一个回调函数,用于更新管道的位置和尺寸,以进行碰撞检测。

updateScoreCallback - 一个回调函数,用于更新玩家的分数。

gameState - 表示游戏的当前状态(例如,正在播放,已完成)。

pipeDimension - 代表顶部,间隙和底部管道的权重的元组。

管道组件根据游戏状态和经过的时间来管理管道的创建和移动。

B)管道数据类

data class Pipe(
val width:Dp = 100.dp,
val topPipeWeight:Float,
val gapWeight:Float,
val bottomPipeWeight:Float,
var position:Dp,
)

Pipe是表示游戏中单个管道的数据类。它包含诸如宽度,顶部,间隙和底部管道的权重以及其在屏幕上的位置等属性。

C)管道生成逻辑

if(System.currentTimeMillis()- PipeTime.lastPipeAddedTime> = 2000L{
//生成新管道并将其添加到列表中
//...
//添加逻辑
val addToList = if(pipes.isNotEmpty()){
abs(pipes.last()。position.minus(newPipe.position)。value)> 500f
} else {
true
}

如果满足条件,则添加到列表中。更新得分回调函数会在生成新管道时调用以更新玩家的分数。

D)管道运动

//从右到左移动管道
LaunchedEffect(key1 = pipes.size,gameState){
while(gameState == GameState.PLAYING){
delay(16L)
pipes = pipes.map {pipe->
val newPosition = pipe.position-pipeSpeed
pipe.copy(position = newPosition)
} .filter {pipe->
pipe.position>-pipeWidth)//从屏幕上删除
}
}
}

使用LaunchedEffect将管道从右向左移动。该效果在游戏处于“播放”状态时运行。

delay(16L)确保以一致的速率移动管道,提供平滑的动画效果。

通过映射每个管道的位置来更新管道列表,减去管道速度(pipeSpeed)。从屏幕上删除的管道(position < -pipeWidth)将从列表中删除。

E)GapPipe组合

@Composable
fun GapPipe(pipe:Pipe,updatePipeRect:(Rect) - > Unit){
//...
}

GapPipe组合负责呈现单个管道及其间隙。

.onGloballyPositioned {
val pipeRect = it.boundsInRoot()
updatePipeRect(pipeRect)
}

它接受一个Pipe对象和一个回调函数updatePipeRect以进行碰撞检测。

F)管道尺寸计算

fun getPipeDimensions(
birdPosition:Rect,
screenHeight:Dp
):Triple<Float,Float,Float> {
//...
}
  • getPipeDimensions函数根据鸟的位置和屏幕高度计算顶部,间隙和底部管道的权重(相对高度)。

  • 它确保生成的管道权重在一定限制范围内,以创建具有挑战性但公平的游戏。

3. 地面和分数显示

Flappy Musketeer游戏中的Ground组合负责呈现显示与游戏相关的信息的地面区域。以下是这个组合的说明
Ground and Score Display

@Composable
fun Ground(
label:String,
score:Long,
enablePause:Boolean = false,
onPauseCallback:() - > Unit = {}{
//...
}

关键点

  • label-表示地面区域的标签或标题的字符串。

  • score-表示玩家得分的长整数。

  • enablePause-一个布尔值,指示是否启用暂停按钮。默认情况下设置为false。

  • onPauseCallback-单击暂停按钮时调用的回调函数。默认情况下,它是一个空函数。

Ground组合创建一个可视的地面区域,显示标签,得分和可选的暂停按钮。它用于提供与游戏进度相关的信息和交互。

4. 游戏按钮
Play Button

@Composable
fun Play(onPlayCallback:() - > Unit){
//...
}

关键点

  • onPlayCallback-此参数是单击播放按钮时将调用的回调函数。通常会触发游戏的开始或重新开始。

  • Play组合创建一个视觉上吸引人的播放按钮,与游戏的主题相匹配。

结论


在Flappy Musketeer游戏中,我们开始了一段充满激情的旅程,利用Jetpack Compose的强大功能创建Android移动游戏。我们深入探讨了主题、导航、游戏菜单和游戏屏幕逻辑,剖析每个方面,为您提供打造自己沉浸式游戏体验所需的工具。

当您踏上游戏开发之旅时,请记住Jetpack Compose为创建视觉上令人惊叹和引人入胜的Android游戏开启了无限可能。因此,前进吧,释放您的创造力,构建出一些酷炫的东西!

GitHub

https://github.com/nirbhayph/flappymusketeer/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1135696.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据-Storm流式框架(三)--Storm搭建教程

一、两种搭建方式 1、storm单节点搭建 2、完全分布式搭建 二、storm单节点搭建 准备 下载地址&#xff1a;Index of /dist/storm 1、环境准备&#xff1a; Java 6 Python 2.6.6 2、上传、解压安装包 3、在storm目录中创建logs目录 mkdir logs 启动 ./storm help …

机器人学导论-约翰 J.克雷格

目录 第五章 雅可比&#xff1a;速度和静力 5.1 刚体的线速度和角速度5.5 机器人连杆运动 第五章 雅可比&#xff1a;速度和静力 5.1 刚体的线速度和角速度 \(V_{BORG}\)是坐标系B在A坐标系下的速度&#xff0c;\(^BV_Q\)是B坐标系下Q的速度&#xff0c;\(^A\Omega\)表示从坐标…

数据分析案例-某公司员工数据信息可视化(文末送书)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

打印机连接网络后怎么安装驱动?

打印机在我们办公和生活中算是比较常见的设备&#xff0c;特别是在上班时需要时常打印各种文件&#xff0c;但是有时电脑上的打印机也会有无法打印的问题&#xff0c;或者新买的打印机需要先安装驱动才能正常打印的。 那么这个时候我们需要先检查电脑上的打印机是否有安装驱动&…

uniapp开发h5 监听用户物理返回键 类似拼多多返回后弹窗

uniapp有个onBackPress生命周期 但是h5中只能监听到navbarr左边的返回按钮以及uni.navigateBack() 方法 h5既然监听不到物理返回键&#xff0c;那么用户点击了物理返回键自然会路由返回上一页&#xff0c;那么我们监听路由&#xff0c;由于路由是uni自己封装的&#xff0c;我测…

3D模型格式转换工具HOOPS Exchange:支持国际标准STEP格式!

HOOPS Exchange SDK是一组C软件库&#xff0c;使开发团队能够快速将可靠的2D和3D CAD导入和导出添加到其应用程序中&#xff0c;访问广泛的数据&#xff0c;包括边界表示 (B-REP)、产品制造信息 (PMI)、模型树、视图、持久 ID、样式、构造几何、可视化等&#xff0c;无需依赖任…

易点易动:引入二维码和移动技术,助力企业高效进行固定资产盘点

固定资产是企业重要的财务资源&#xff0c;而高效准确地进行海量固定资产盘点一直是企业管理的挑战。为了解决这一问题&#xff0c;易点易动固定资产管理系统引入了先进的二维码和移动技术。本文将详细介绍易点易动固定资产管理系统的二维码和移动技术&#xff0c;展示如何借助…

深度学习入门:一篇概述深度学习的文章

文章目录 &#x1f31f; 特征工程&#xff1a;推荐系统有哪些可供利用的特征&#xff1f;&#x1f34a; 1. 用户特征&#x1f34a; 2. 商品特征&#x1f34a; 3. 上下文特征&#x1f34a; 4. 社交特征&#x1f34a; 5. 行为特征 &#x1f31f; 特征处理&#xff1a;如何利用Spa…

【C++】list的介绍及使用 | 模拟实现list(万字详解)

目录 一、list的介绍及使用 什么是list&#xff1f; list的基本操作 增删查改 获取list元素 不常见操作的使用说明 ​编辑 接合splice ​编辑 移除remove 去重unique 二、模拟实现list 大框架 构造函数 尾插push_back 迭代器__list_iterator list的迭代器要如何…

Java八股文 ---Java并发篇

线程安全 线程安全就是多个线程去执行某类&#xff0c;这个类始终能表现出正确的行为&#xff0c;那么这个类就是线程安全的 我们判断是否要处理线程安全问题&#xff0c;就看有没有多个线程同时访问一个共享变量 能不能保证操作的原子性&#xff0c;考虑atomic包下的类够不够我…

DASCTF X CBCTF 2023

一、justpaint 1.先是压缩包密码爆破&#xff0c;密码为11452&#xff0c;然后开始代码审计&#xff0c;发现是一个线性的神经网络。 源代码如下&#xff1a; import torch import torch.nn as nn import numpy as np import matplotlib.pyplot as plt from PIL import Ima…

JVM重点

文章目录 0. 运行流程1. 内存区域划分1.1 堆1.2 Java 虚拟机栈1.3 程序计数器1.4 方法区 2. 类加载机制类加载过程2.1 加载2.2 验证2.3 准备2.4 解析2.5 初始化双亲委派模型 3. 垃圾回收机制3.1 垃圾判断算法3.1.1 引用计数算法3.1.2 可达性分析算法 3.2 垃圾回收算法3.2.1 标记…

01 # 手写 new 的原理

new 做了什么? 在构造器内部创建一个新的对象这个对象内部的隐式原型指向该构造函数的显式原型让构造器中的 this 指向这个对象执行构造器中的代码如果构造器中没有返回对象&#xff0c;则返回上面的创建出来的对象 手写 new 的过程 new 是一个运算符&#xff0c;只能通过函…

Redis Cluster高可用集群原理

目录 一、Redis Cluster和哨兵对比二、槽位定位算法三、集群节点间的通信机制四、集群选举原理五、网络抖动六、Redis集群为什么至少需要三个master节点&#xff0c;并且推荐节点数为奇数&#xff1f;七、集群没有过半机制会出现脑裂数据丢失问题八、跳转重定位九、集群对批量操…

封神工具:腾讯云服务器价格计算器,精准报价一键计算!

腾讯云服务器价格计算器可以一键计算出云服务器的精准报价&#xff0c;包括CVM实例规格价格、CPU内存费用、公网带宽收费、存储系统盘和数据盘详细费用&#xff0c;腾讯云百科txybk.com分享腾讯云价格计算器链接入口、使用方法说明&#xff1a; 腾讯云服务器价格计算器 打开腾…

行业追踪,2023-10-25

自动复盘 2023-10-25 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

[奇奇怪怪符号]输入法手动输入希腊字母

日常写材料总要输入一些奇奇怪怪符号&#xff0c;虽然知道有一张表&#xff0c;可以在上面选&#xff0c;但是在文本编辑器上找到并打开也不是一件容易的事情&#xff0c;&#xff08;功能多的编辑器就很臃肿&#xff0c;令人眼花缭乱的标签&#xff09; 很想要简洁的编辑器&a…

文件加密软件(2023十大文件加密软件排行榜)

文件加密软件已成为企业和个人保护文件安全的重要工具。本文将介绍2023年十大文件加密软件的排行榜&#xff0c;以帮助大家了解和选择适合自己的文件加密软件。 本文是根据软件的功能性、安全性、易用性和创新性等多方面指标进行评选&#xff0c;以体现各大文件加密软件的实力和…

C++多态的认识与理解

多态的概念 通俗来说&#xff0c;多态就是多种形态。具体点就是去完成某个行为&#xff0c;当不同的对象去完成时会产生出不同的状态。 比方说买高铁票时&#xff0c;如果你是学生的话&#xff0c;买票就有优惠。如果你是军人的话&#xff0c;就可以优先买票。普通人的话&…

聚观早报 |2024年春节连休8天;RTE2023开幕

【聚观365】10月26日消息 2024年春节连休8天 RTE2023开幕 一加12首发“东方屏” 微软公布2024财年第一财季财报 Alphabet Q3业绩好于预期 2024年春节连休8天 国务院办公厅发布关于2024年部分节假日安排的通知。2024年春节&#xff0c;2月10日至17日放假调休&#xff0c;共…