【Android开发基础】Canvas画笔(以刮刮乐为例)

news2025/4/7 14:08:34

文章目录

    • 一、引言
    • 二、设计
      • 1、获取图片资源
      • 2、获取屏幕信息
      • 3、Canvas涂层
      • 4、随机内容
      • 5、屏幕监听
    • 三、附件
      • 1、UI设计
      • 2、总代码
        • (1)控件初始化
        • (2)图层初始化
      • 3、源代码

一、引言

本篇博客只说明Canvas画笔的使用,关于案例仅供学习,禁止非法使用

  • 描述:如何使用Canvas将图片资源绘画出来,并通过触感传感器做到清除功能。广泛应用于 活动抽奖、游戏领域。其中尤为著名的游戏有 小鳄鱼爱洗澡
  • 难度:中级
  • 知识点:
    1、Bitmap资源的使用
    2、Canvas画笔
  • 效果
    在这里插入图片描述

二、设计

1、获取图片资源

对上层资源(刮的图层)进行解析

Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.scratch_card);
Bitmap alterBitmap = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),bitmap.getConfig());

2、获取屏幕信息

收集屏幕信息

DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);

double NX = bitmap.getWidth()/dm.widthPixels;
double NY = bitmap.getHeight()/dm.heightPixels;

3、Canvas涂层

适应屏幕进行涂顶层图层

//创建一个canvas对象
Canvas canvas = new Canvas(alterBitmap);
//画笔
Paint paint = new Paint();
//设置颜色
paint.setColor(Color.BLACK);
paint.setAntiAlias(true);
//Matrix对象
Matrix matrix = new Matrix();
//画图
canvas.drawBitmap(bitmap,matrix,paint);

4、随机内容

Random方法随机一个值

//随机抽奖
Random XingYun = new Random();
int kelang = XingYun.nextInt(3);
String[] deng = {"一等奖","二等奖","三等奖"};
text_bg.setText(deng[kelang]);

5、屏幕监听

完成消除上层图层指定位置的Bitmap内容

bg.setOnTouchListener(new View.OnTouchListener(){
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        try {
            int x = (int)event.getX();
            int y = (int)event.getY();
            for (int i = -100 ; i<100 ; i++){
                for (int j = -100 ; j<100 ; j++){
                    if (Math.sqrt((i*i) + (j*j)) <= 100){
                        alterBitmap.setPixel((int)(x*NX) + i , (int) (y*NY +90)+j , Color.TRANSPARENT);
                    }
                }
            }
            bg.setImageBitmap(alterBitmap);
        }catch (Exception e){
            e.printStackTrace();
        }
        return true;
    }
});

三、附件

1、UI设计

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/text_bg"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="50dp" />

    <ImageView
        android:id="@+id/image_bm"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="centerCrop"
        android:src="@drawable/scratch_card"/>

</RelativeLayout>

2、总代码

(1)控件初始化

    private void init() {
        bg = findViewById(R.id.image_bm);
        text_bg = findViewById(R.id.text_bg);

        //随机抽奖
        Random XingYun = new Random();
        int kelang = XingYun.nextInt(3);
        String[] deng = {"一等奖","二等奖","三等奖"};
        text_bg.setText(deng[kelang]);
    }

(2)图层初始化

    private void initImage() {
        //资源解析
        Bitmap bitmap =
                BitmapFactory.decodeResource(getResources(),R.drawable.scratch_card);
        alterBitmap = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),bitmap.getConfig());
        //收集屏幕信息
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);

        //适应屏幕
        NX = bitmap.getWidth()/dm.widthPixels;
        NY = bitmap.getHeight()/dm.heightPixels;

        //创建一个canvas对象
        Canvas canvas = new Canvas(alterBitmap);
        //画笔
        Paint paint = new Paint();
        //设置颜色
        paint.setColor(Color.BLACK);
        paint.setAntiAlias(true);
        //Matrix对象
        Matrix matrix = new Matrix();
        //画图
        canvas.drawBitmap(bitmap,matrix,paint);
        //监听
        bg.setOnTouchListener(new View.OnTouchListener(){

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                try {
                    int x = (int)event.getX();
                    int y = (int)event.getY();
                    for (int i = -100 ; i<100 ; i++){
                        for (int j = -100 ; j<100 ; j++){
                            if (Math.sqrt((i*i) + (j*j)) <= 100){
                                alterBitmap.setPixel((int)(x*NX) + i , (int) (y*NY +90)+j , Color.TRANSPARENT);
                            }
                        }
                    }
                    bg.setImageBitmap(alterBitmap);
                }catch (Exception e){
                    e.printStackTrace();
                }
                return true;
            }
        });
    }

3、源代码

CSDN:https://download.csdn.net/download/weixin_48916759/87920165
 
gitee:https://gitee.com/xu-pq/android-demo/tree/master/CanvasDemo

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

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

相关文章

STM32单片机(六)TIM定时器 -> 第六节:TIM输入捕获练习(输入捕获模式测频率和PWMI模式测频率占空比)

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

docker inspect

docker inspect 命令用于获取有关 Docker 容器、镜像、网络等的详细信息。它提供了关于指定对象的元数据和配置的完整视图&#xff0c;包括运行状态、网络设置、卷挂载、环境变量等。 以下是一些常见的字段和属性&#xff0c;可以根据需要选择其中一些或全部列出&#xff1a; …

【算法与数据结构】202、LeetCode快乐数

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;先用一个dowhile循环计算整数各个位数字的平方和&#xff0c;然后在unordered_set里面插入n&#xff0…

C语言学习笔记:函数

✨博文作者&#xff1a;烟雨孤舟 &#x1f496; 喜欢的可以 点赞 收藏 关注哦~~ ✍️ 作者简介: 一个热爱大数据的学习者 ✍️ 笔记简介&#xff1a;作为大数据爱好者&#xff0c;以下是个人总结的学习笔记&#xff0c;如有错误&#xff0c;请多多指教&#xff01; 目录 简介 …

关于OpenCV中minAreaRect角度记录

一、问题引出 最近看到stackflow关于minAreaRect的讨论&#xff1a; MinAreaRect angles - Unsure about the angle returnedOpenCV’s RotatedRect angle does not provide enough information 大概问题是minAreaRect这个接口返回的角度信息不足以反应返回的旋转矩形的旋转…

appium辅助自动化工具-- Appium studio

这里我要给大家介绍一款appium辅助自动化测试工具appium studio&#xff0c;你没看错&#xff0c;不是android studio&#xff0c;也不是appium android studio&#xff0c;就是appium studio&#xff01; 下载地址&#xff1a; Appium Studio | Digital.ai Continuous Test…

架构-计算机体系结构

章节架构 分值约 3 分 #mermaid-svg-nV7dvQlYnuXaOVOf {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-nV7dvQlYnuXaOVOf .error-icon{fill:#552222;}#mermaid-svg-nV7dvQlYnuXaOVOf .error-text{fill:#552222;strok…

如何优雅的使用 React Context

在开始今天的文章之前&#xff0c;大家不妨先想一下触发 React 组件 re-render 的原因有哪些&#xff0c;或者说什么时候 React 组件会发生 re-render 。 先说结论&#xff1a; 状态变化父组件 re-renderContext 变化Hooks 变化 ❝ 这里有个误解&#xff1a;props 变化也会导致…

力扣日记2481

1. 题目 LeetCode 2481. 分割圆的最少切割次数 1.1 题意 可以使用直接或半径切分&#xff0c;管他叫一次切分&#xff0c;求切分圆为n等份的最少次数。 1.2 分析 可以想到&#xff0c;对圆做n等分&#xff0c;然后每个半径看出一次切分&#xff0c;这是最多次数&#xff0c;…

实验篇(7.2) 13. 站对站安全隧道 - 走对方宽带上网(FortiGate-IPsec) ❀ 远程访问

【简介】前面实验已经知道&#xff0c;FortiClient客户端拨号到远端防火墙&#xff0c;包括上网流量等所有流量都可以通过隧道到达远端防火墙&#xff0c;并从对方宽带上网。那么两台防火墙之间连接的安全隧道&#xff0c;可以实现这个功能吗&#xff1f; 实验要求与环境 OldMe…

uniapp中使用mixins(混入)使用

mixins 选项接收一个混入对象的数组。这些混入对象可以像正常的实例对象一样包含实例选项&#xff0c;这些选项将会被合并到最终的选项中&#xff0c;使用的是和 Vue.extend() 一样的选项合并逻辑。也就是说&#xff0c;如果你的混入包含一个 created 钩子&#xff0c;而创建组…

虚拟网络namespace到bridge

前言 容器的网络是一大难点&#xff0c;不管是docker 还是kubernetes 都绕不开计算机网络。以下的介绍主要以计算机网络的namespace 和bridge 两个方面来展开介绍&#xff0c;方便深入理解容器的网络原理。 1.namespace分析 linux 支持六种资源的namespace :mount ns 、UTS ns…

HTML日期选择器:简化日期输入与交互

Date Picker 控件 HTML提供了<input>元素的type="date"属性,用于创建日期选择器(Date Picker)控件。日期选择器允许用户从一个交互式日历中选择日期值。以下是关于HTML日期选择器的详细解释: 创建日期选择器: 使用<input>元素,并将其type属性设置…

java从零开始系统性学习完整超全资源+笔记(下)

java从零开始系统性学习完整超全资源笔记&#xff08;下&#xff09; java从零开始系统性学习完整超全资源笔记&#xff08;上&#xff09; 文章目录 java从零开始系统性学习完整超全资源笔记&#xff08;下&#xff09;第十七章 泛型与常见数据结构ArrayListCollection接口的…

linux + lnmp + tp6部署项目问题集

部署完毕后&#xff0c;访问域名&#xff0c;报错502 Gateway 1:查看防火墙&#xff0c;需要的端口是否被关闭了&#xff0c;需要开启 vi /etc/sysconfig/iptables 发现有端口没空&#xff0c;就先i,然后把该端口后面的DROP改成ACCEPT&#xff0c;然后esc :wq 再回车&#xf…

轻松搞定文件复制备份,教你用快速的时间将文件复制另一个文件夹里并自动编号。

通常情况下&#xff0c;我们会将文件复制到另一个文件夹中&#xff0c;这很容易实现。但是如果需要将大量文件复制到同一个文件夹中&#xff0c;并且需要给每个文件自动编号&#xff0c;这时就需要用到一些技巧了。下面是一个简单的办法&#xff0c; 首先&#xff0c;第一步我…

node笔记_读写excel

文章目录 ⭐前言⭐安装依赖⭐读取excel&#x1f496; 按行读取&#x1f496; 按列读取 ⭐写入excel⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于node读取excel内容 往期文章 node_windows环境变量配置 node_npm发布包 linux_配置node node_nvm安装配置…

微服务开发系列 第十一篇:XXL-JOB

总概 A、技术栈 开发语言&#xff1a;Java 1.8数据库&#xff1a;MySQL、Redis、MongoDB、Elasticsearch微服务框架&#xff1a;Spring Cloud Alibaba微服务网关&#xff1a;Spring Cloud Gateway服务注册和配置中心&#xff1a;Nacos分布式事务&#xff1a;Seata链路追踪框架…

【AIGC】baichuan-7B大模型

百川智能&#xff5c;开源可商用的大规模预训练语言模型baichuan-7B大模型 概述 baichuan-7B 是由百川智能开发的一个开源可商用的大规模预训练语言模型。基于 Transformer 结构&#xff0c;在大约1.2万亿 tokens 上训练的70亿参数模型&#xff0c;支持中英双语&#xff0c;上…

day53_spring

今日内容 零、 复习昨日 零、 复习昨日 略 一、代理设计模式 代理的设计理念是限制对象的直接访问&#xff0c;即不能通过 new 的方式得到想要的对象&#xff0c;而是访问该对象的代理类。 这样的话&#xff0c;我们就保护了内部对象&#xff0c;如果有一天内部对象因为 某个原…