jjzjj

android - 缩放固定的 SurfaceView 以垂直填充并保持纵横比

coder 2023-12-12 原文

我一直在努力寻找答案,但似乎找不到答案(这是一种相当非常规的 Android 游戏编程方法,所以这是意料之中的,至少我认为是这样)。

我正在尝试在 Android 中创建一个 GBA 风格的 RPG 游戏(出于怀旧之情)。 OpenGL 对我来说不够好,因为它在游戏循环中的可定制性不够(我只想在需要绘制某些东西时调用 draw,因为我希望这款游戏在使用方式上非常高效电池,这意味着让它更像是一个投票应用程序而不是游戏)。我创建了一个自定义表面 View ,它有自己的线程,只要需要完成绘图就会被调用(我在 SDK 中的示例 LunarLander android 游戏之后对其进行了建模)。

问题是,我希望游戏本身具有固定大小 (208x160),然后放大到屏幕大小。我遇到的问题是,在 XML 中的扩展 SurfaceView 的正常参数中,似乎无论如何都无法这样做。当前状态下的游戏如下图所示。我试图让它拉伸(stretch)到屏幕的高度并保持宽度的比例,同时也不增加可观看的游戏(保持它固定,无论屏幕尺寸如何)。

/image/EWIdE.png (我打算在线发布实际图像。防止垃圾邮件会咬我>.<>

目前,我正在获取 SurfaceView 的 Canvas 并直接在其上绘图,并将我的尺寸作为硬编码像素尺寸(208 像素、160 像素)提供。

这是线程当前在获取 Canvas 并绘制到 Canvas 时的样子。在不改变我希望游戏虚拟占用的大小的情况下,有什么更好的方法可以绘制到 Canvas 上?

@Override
    public void run()
    {
        Canvas c = null;
        try
        {
            c = surfaceHolder.lockCanvas(null);
            synchronized (surfaceHolder)
            {
                draw(c);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (c != null)
                surfaceHolder.unlockCanvasAndPost(c);
        }
    }

绘制方法是这样的(StringBuilder是我自己在引擎中编码的Object):

public void draw(Canvas canvas)
{       
    canvas.drawColor(Color.GRAY);
    StringBuilder stringBuilder = new StringBuilder(canvas, Color.BLACK, letters);
    stringBuilder.drawString("Oh, hello there!");
    stringBuilder.setLocation(10, 20);
    stringBuilder.drawString("Why am I so small?");
}

有什么想法吗?

最佳答案

假设您的 draw 函数被重命名为 drawBase。以下是您的操作方法:

public void draw(Canvas canvas)
{
    final float scaleFactor = Math.min( getWidth() / 208.f, getHeight() / 160.f );
    final float finalWidth = 208.f * scaleFactor;
    final float finalHeight = 160.f * scaleFactor;
    final float leftPadding = ( getWidth() - finalWidth ) / 2;
    final float topPadding =  ( getHeight() - finalHeight ) / 2;

    final int savedState = canvas.save();
    try {
        canvas.clipRect(leftPadding, topPadding, leftPadding + finalWidth, topPadding + finalHeight);

        canvas.translate(leftPadding, topPadding);
        canvas.scale(scaleFactor, scaleFactor);

        drawBase(canvas);
    } finally {
        canvas.restoreToCount(savedState);
    }
}

关于android - 缩放固定的 SurfaceView 以垂直填充并保持纵横比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10707519/

有关android - 缩放固定的 SurfaceView 以垂直填充并保持纵横比的更多相关文章

  1. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  2. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  3. ruby - 在 Ruby 中将整数格式化为固定长度的字符串 - 2

    有没有一种简单的方法可以将给定的整数格式化为具有固定长度和前导零的字符串?#convertnumberstostringsoffixedlength3[1,12,123,1234].map{|e|???}=>["001","012","123","234"]我找到了解决方案,但也许还有更聪明的方法。format('%03d',e)[-3..-1] 最佳答案 如何使用%1000而不是进行字符串操作来获取最后三位数字?[1,12,123,1234].map{|e|format('%03d',e%1000)}更新:根据theTinMan的

  4. ruby - 在 Ruby 中,垂直线是什么? - 2

    1.upto(9){|x|printx}为什么这行不通?{printx|x}}y呢? 最佳答案 它用于传递给您的block的参数。即在您的示例中,upto将使用1到9中的每个数字调用您的block,当前值可作为x获得。block参数可以有任何名称,就像方法参数一样。例如1.upto(9){|num|putsnum是有效的。就像一个方法的参数一样,一个block也可以有多个参数。例如hash.each_pair{|key,value|puts"#{key}is#{value}"} 关于ru

  5. ruby - 如何保持我不常用的编程语言技能 - 2

    关闭。这个问题是off-topic.它目前不接受答案。想改进这个问题吗?Updatethequestion所以它是on-topic用于堆栈溢出。关闭11年前。Improvethisquestion我不经常使用ruby​​-通常它加起来相当于每两个月或更长时间编写一次脚本。我的大部分编程都是使用C++进行的,这与ruby​​有很大不同。由于我与ruby​​之间的差距如此之大,我总是忘记语言的基本方面(比如解析文本文件和其他简单的东西)。我想每天练习一些基本的东西,我想知道是否有一些我可以订阅的网站,并且会向我发送当天的Ruby问题或类似的东西。有人知道这样的站点/Internet服务吗?

  6. ruby - 如何在 Ruby 中返回整数的固定长度二进制表示? - 2

    我知道我可以使用Fixnum#to_s将整数表示为二进制格式的字符串。但是1.to_s(2)生成1而我希望它生成00000001。我怎样才能使所有返回的字符串都以零作为填充到8个字符?我可以使用类似的东西:binary="#{'0'*(8-(1.to_s(2)).size)}#{1.to_s(2)}"if(1.to_s(2)).size但这看起来不是很优雅。 最佳答案 使用字符串格式。"%08b"%1#=>"00000001" 关于ruby-如何在Ruby中返回整数的固定长度二进制表示?

  7. Ruby 数组 - 如何使值在 nil 值上保持不变 - 2

    我正在处理一系列midi音高,看起来像这样......pitches=[60,nil,nil,nil,67,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil]在这种情况下,索引1、2和3上的间距仍然是60。索引4之后,音高仍然是67。如何编写一个方法来识别先前的非零值?目前我能想到的唯一方法看起来有点笨拙:defpitch_at_step(pitches,step)ifpitches.any?x=pitches[step]

  8. Ruby 固定数字大十进制舍入 - 2

    我想用ruby​​对BigDecimal进行舍入。我知道我可以使用round函数但是轮函数给出(3.2).round(2)=>3.2我要(3.2).round(2)=>3.20(3.20).round(2)=>3.20(3).round(2)=>3.00(3.578).round(2)=>3.58我总是希望有2位小数,3.20而不是3.2知道如何完成这项工作吗? 最佳答案 试试这个:'%.2f'%3.2=>"3.20"'%.2f'%3=>"3.00"'%.2f'%3.578=>"3.58"etc.

  9. ruby - 防止 ruby​​ sinatra 中的 session 固定 - 2

    ruby中的大多数session固定主题都与Rails相关。sinatra中是否存在任何session固定漏洞?在rails中,我们通常建议在分配session之前执行reset_session。我们如何防止sinatra中的session固定? 最佳答案 Sinatra默认使用Rack::Protectiongem来防止许多常见漏洞。您可能对其session劫持保护特别感兴趣。这些是Rack::Protectiongem防止的一些事情:跨站请求伪造真实性token:如果给定的访问token与session中包含的token相匹配,

  10. ruby - 将 cucumber 步骤或步骤文件限制为指定的功能或标签 - 2

    我为我们的网络应用程序编写了一个模态幻灯片,它提供了一组文档的导航并公开了这些文档的各种元数据。这是一个具有深奥需求的应用程序的大型组件,因此我认为它的核心场景(作为验收标准提供给我)应该既多又内部一致是很公平的。为了避免对我们的许多场景中的每一个都有一个新的步骤,我已经改编了ahelper将人类可读的术语(例如documentcaption)翻译成选择器:moduleSelectorsHelperdefselector_for(term)caseterm#Lightbox/modal/fancyboxwhen'lightbox''#fancybox-inner'when'closeb

随机推荐