android手机游戏之二线程绘图
2011-04-06 13:04
417 查看
在之前我写了一个简单的手工绘图,现在接下来继续讲解下加了线程绘图使界面更加的丰富多彩..
首先是目录结构:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/3f9cf775f625392aebf561709979c4ed.gif)
步骤一:建立AFootballactivity主类。二:建立CustomGallery自定义类(这个拿来用就可以了)。三:WelcomeView类.四WelcomeThread类。五:WelcomeDrawThread.
材料图片部分:(将一下图片分别放入drawable-mdpi文件)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/373518859ab77b28b14975f0452481a9.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/decf63a8cd0d890ac7a2a991f1ba51f3.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/a55dcf94f95c9197186aff36c9667f02.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/0168603c288ba0960b253e0274e9b25b.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/b23900b9763824f076daf9b97b10487e.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/3dc5419f7856c504f83677f2fe9a6a3a.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/abbb0b32583ffabac40c07f952317640.gif)
图片名称:p1.jpg , p2.jpg ,p3.jpg,welcome.jpg,club_4.png,club_5.png,club_6.png。以上工作全部准备好了就进入代码部分.
1.AFootballActivity类
2.CustomGallery类
3.WelcomeView类
4.WelcomeThread类
5.WelcomeDrawThread
最后的效果图:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/f3f613c9a55e1bdd4b3d7ace125cdd98.gif)
5个类以建立完成...
首先是目录结构:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/3f9cf775f625392aebf561709979c4ed.gif)
步骤一:建立AFootballactivity主类。二:建立CustomGallery自定义类(这个拿来用就可以了)。三:WelcomeView类.四WelcomeThread类。五:WelcomeDrawThread.
材料图片部分:(将一下图片分别放入drawable-mdpi文件)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/373518859ab77b28b14975f0452481a9.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/decf63a8cd0d890ac7a2a991f1ba51f3.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/a55dcf94f95c9197186aff36c9667f02.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/0168603c288ba0960b253e0274e9b25b.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/b23900b9763824f076daf9b97b10487e.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/3dc5419f7856c504f83677f2fe9a6a3a.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/abbb0b32583ffabac40c07f952317640.gif)
图片名称:p1.jpg , p2.jpg ,p3.jpg,welcome.jpg,club_4.png,club_5.png,club_6.png。以上工作全部准备好了就进入代码部分.
1.AFootballActivity类
package com.AFootball; import android.app.Activity; import android.content.Context; import android.graphics.Rect; import android.media.MediaPlayer; import android.os.Bundle; import android.view.View; import android.view.Window; import android.view.WindowManager; public class AFootballActivity extends Activity { View current; WelcomeView welcome; int keyState = 0; boolean wantSound = true; // 是否播放声音标志位 MediaPlayer mpWelcomeMusic; // 游戏开始前的欢迎音乐 Rect rectGallery; // 表示Gallery的矩形框 int[] imageIDs = { // 存放8个俱乐部的图片ID R.drawable.club_1, R.drawable.club_2, R.drawable.club_3, R.drawable.club_4, R.drawable.club_5, R.drawable.club_6, R.drawable.club_7, R.drawable.club_8 }; int clubID = imageIDs[0]; // 记录用户选择的俱乐部的ID @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initWelcomeSound(this); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); welcome = new WelcomeView(this);// 将屏幕切到欢迎界面 setContentView(welcome); current = welcome; if (wantSound && mpWelcomeMusic != null) { mpWelcomeMusic.start(); } initRects();// 初始化用于匹配点击事件的矩形框 } // 方法:初始化欢迎界面的声音 private void initWelcomeSound(Context context) { mpWelcomeMusic = MediaPlayer.create(context, R.raw.music); } // 方法:初始化矩形框 private void initRects() { rectGallery = new Rect(10, 10, 310, 110); } }
2.CustomGallery类
package com.AFootball; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; public class CustomGallery { Bitmap[] bmpContent; // Gallery要显示的内容图片 int length; // Gallery要显示的图片数组大小 int currIndex; // 当前被显示的图片的索引 int startX; // 绘制Gallery时其左上角在屏幕中的X坐标 int startY; // 绘制Gallery时其左上角在屏幕中的Y坐标 int cellWidth; // 每个图片的宽度 int cellHeight; // 每个图片的高度 // 构造器,初始化主要成员变量 public CustomGallery(int startX, int startY, int cellWidth, int cellHeight) { this.startX = startX; this.startY = startY; this.cellWidth = cellWidth; this.cellHeight = cellHeight; } public void setContent(Bitmap[] bmpContent) { // 方法:为Gallery设置显示内容 this.bmpContent = bmpContent; this.length = bmpContent.length; } public void setCurrent(int index) { // 方法:设置当前显示的图片 if (index >= 0 && index < length) { this.currIndex = index; } } public void drawGallery(Canvas canvas, Paint paint) {// 方法:绘制自己 // 创建背景的画笔 Paint paintBack = new Paint(); paintBack.setARGB(220, 99, 99, 99); // 创建边框的画笔 Paint paintBorder = new Paint(); paintBorder.setStyle(Paint.Style.STROKE); paintBorder.setStrokeWidth(4.5f); paintBorder.setARGB(255, 150, 150, 150); // 画左边的图片 if (currIndex > 0) { canvas.drawRect(startX, startY, startX + cellWidth, startY + cellHeight, paintBack); // 背景 canvas.drawBitmap(bmpContent[currIndex - 1], startX, startY, paint); // 贴图片 canvas.drawRect(startX, startY, startX + cellWidth, startY + cellHeight, paintBorder); // 画左边图片的边框 } // 画被选中的图片 canvas.drawRect(startX + cellWidth, startY, startX + cellWidth * 2, startY + cellHeight, paintBack); // 背景 canvas.drawBitmap(bmpContent[currIndex], startX + cellWidth, startY, paint); // 贴图片 // 画右边的图片 if (currIndex < length - 1) { canvas.drawRect(startX + cellWidth * 2, startY, startX + cellWidth * 3, startY + cellHeight, paintBack); // 背景 canvas.drawBitmap(bmpContent[currIndex + 1], startX + cellWidth * 2, startY, paint); // 贴图片 paintBorder.setARGB(255, 150, 150, 150); // 画右边图片的边框 canvas.drawRect(startX + cellWidth * 2, startY, startX + cellWidth * 3, startY + cellHeight, paintBorder); } // 画选中的边框 paintBorder.setColor(Color.RED); canvas.drawRect(startX + cellWidth, startY, startX + cellWidth * 2, startY + cellHeight, paintBorder); } public void galleryTouchEvnet(int x, int y) { // 方法:Gallery的处理点击事件方法 if (x > startX && x < startX + cellWidth) { // 点在了左边那张图片 if (currIndex > 0) { // 判断当前图片的左边还有没有图片 currIndex--; // 设置当前图片为左边的图片 } } else if (x > startX + cellWidth * 2 && x < startX + cellWidth * 3) { // 点在了右边那张图片 if (currIndex < length - 1) { // 判断当前图片的右边还有没有图片 currIndex++; // 设置当前图片为右边的图片 } } } }
3.WelcomeView类
package com.AFootball; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.view.SurfaceHolder; import android.view.SurfaceView; public class WelcomeView extends SurfaceView implements SurfaceHolder.Callback { WelcomeThread wt; // 后台修改数据线程 WelcomeDrawThread wdt; // 后台重绘线程 int index = 0; // 开场3个动画帧的索引 int status = -1; // 0代表足球动画,1代表背景转进来,2代表全部渐显,3代表待命 int alpha = 255; // 透明度,初始为255,即不透明 int[] layout = { 3, 3, 4 }; // 玩家球员的站位数组,3个值分别代表前场、中场、后场 CustomGallery cg; // 自定义的Gallery类,用于选择俱乐部logo Bitmap[] bmpGallery; // 存储Gallery对象要显示的内容 Bitmap[] bmpAnimaition; // 存储欢迎动画帧的数组 Bitmap bmpBack; // 背景图片 Matrix matrix; // Matrix对象,用来旋转背景图 AFootballActivity father; // Activity的引用 public WelcomeView(AFootballActivity father) { super(father); this.father = father; getHolder().addCallback(this); initBitmap(father); // 初始化图片 matrix = new Matrix(); // 创建Matrix对象 cg = new CustomGallery(10, 10, 100, 100); // 创建CustomGallery对象 cg.setContent(bmpGallery); // 为CustomGallery对象设置显示内容 cg.setCurrent(2); wt = new WelcomeThread(this); // 创建WelcomeThread对象 wdt = new WelcomeDrawThread(this, getHolder()); // 创建WelcomeDrawThread对象 status = 0; // 设置初始状态值为0 } private void initBitmap(Context context) { Resources r = context.getResources(); // 获取Resources对象 bmpBack = BitmapFactory.decodeResource(r, R.drawable.welcome); // 创建背景图片 bmpAnimaition = new Bitmap[3]; // 创建动画数组 bmpAnimaition[0] = BitmapFactory.decodeResource(r, R.drawable.p1); bmpAnimaition[1] = BitmapFactory.decodeResource(r, R.drawable.p2); bmpAnimaition[2] = BitmapFactory.decodeResource(r, R.drawable.p3); // 初始化Gallery的图片资源 bmpGallery = new Bitmap[8]; // 创建自定义Gallery要显示的内容图片数组 for (int i = 0; i < bmpGallery.length; i++) { bmpGallery[i] = BitmapFactory.decodeResource(r, father.imageIDs[i]); } } public void doDraw(Canvas canvas) {// 方法:用于根据不同状态绘制屏幕 Paint paint = new Paint(); // 创建画笔 switch (status) { case 0:// 显示3个动画帧 canvas.drawBitmap(bmpAnimaition[index], 0, 0, null); break; case 1:// 背景图片旋转而进 canvas.drawColor(Color.BLACK); // 清屏幕 Bitmap bmpTemp = Bitmap.createBitmap(bmpBack, 0, 0, bmpBack.getWidth(), bmpBack.getHeight(), matrix, true);// 旋转背景图 canvas.drawBitmap(bmpTemp, 0, 0, null); // 绘制背景图 break; case 2:// 全场透明 case 3:// 全场待命--------------这两个画法一样,只是透明度不同 canvas.drawColor(Color.BLACK); // 清屏幕 paint.setAlpha(alpha); // 设置透明度 canvas.drawBitmap(bmpBack, 0, 0, paint);// 画背景 cg.drawGallery(canvas, paint); // 画自定义的Gallery break; } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder holder) { if (!wt.isAlive()) { // 启动后台修改数据线程 wt.start(); } if (!wdt.isAlive()) { // 启动后台绘制线程 wdt.start(); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { if (wt.isAlive()) { // 停止后台修改数据线程 wt.isWelcoming = false; } if (wdt.isAlive()) { // 停止后台绘制线程 wdt.flag = false; } } }
4.WelcomeThread类
package com.AFootball; public class WelcomeThread extends Thread { WelcomeView father; // WelcomeView对象的引用 boolean isWelcoming = false; // 线程执行标志位 float rotateAngle = 60; // 旋转角度 int rotateCounter = 0; // 旋转计数器 int animationCounter = 0; // 换帧计数器 int sleepSpan = 150; // 休眠时间 // 构造器:初始化主要成员变量 public WelcomeThread(WelcomeView father) { this.father = father; isWelcoming = true; } public void run() {// 线程的执行方法 while (isWelcoming) { switch (father.status) {// 获取现在的状态 case 0: // 该状态为3个图片轮流显示 animationCounter++; // 换帧计数器自加 if (animationCounter == 4) { // 计数器达到4时换帧 father.index++; // 开场3个动画帧的索引 if (father.index == 3) { // 判断是否播放完毕所有帧 father.status = 1; // 转入下一状态 } animationCounter = 0; // 清空计数器 } break; case 1:// 该状态为背景图片旋转着进来 father.matrix.postRotate(rotateAngle); // 旋转角度 rotateCounter++; // 计数器自加 if (rotateCounter == 6) {// 旋转计数器到了 father.status = 2;// 设置状态 father.alpha = 0; // 设置alpha值,用于菜单渐显 } break; case 2:// 该状态为菜单渐显菜单渐显 , alpha透明度,初始为255,即不透明 father.alpha += 51; // alpha值增加 if (father.alpha >= 255) { father.status = 3;// 进入待命状态,此状态玩家可以选择菜单选项 } break; case 3: // 如果遇到了待命状态,就自己把自己关闭 this.isWelcoming = false; break; } try { Thread.sleep(sleepSpan); // 休眠一段时间 } catch (Exception e) { e.printStackTrace(); // 捕获并打印异常 } } } }
5.WelcomeDrawThread
package com.AFootball; import android.graphics.Canvas; import android.view.SurfaceHolder; public class WelcomeDrawThread extends Thread { WelcomeView father; // WelcomeView对象的引用 SurfaceHolder surfaceHolder; // WelcomeView对象的SurfaceHolder int sleepSpan = 100; // 休眠时间 boolean flag; // 线程执行标志位 // 构造器:初始化主要的成员变量 public WelcomeDrawThread(WelcomeView father, SurfaceHolder surfaceHolder) { this.father = father; this.surfaceHolder = surfaceHolder; this.flag = true; } // 方法:线程执行方法 public void run() { Canvas canvas = null; // 创建一个Canvas对象 while (flag) { try { canvas = surfaceHolder.lockCanvas(null); // 为画布加锁 synchronized (surfaceHolder) { father.doDraw(canvas); // 重新绘制屏幕 } } catch (Exception e) { e.printStackTrace(); // 捕获异常并打印 } finally { if (canvas != null) {// 释放画布并将其传回 surfaceHolder.unlockCanvasAndPost(canvas); } } try { Thread.sleep(sleepSpan); // 休眠一段时间 } catch (Exception e) { e.printStackTrace(); // 捕获异常并打印 } } } }
最后的效果图:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/14/f3f613c9a55e1bdd4b3d7ace125cdd98.gif)
5个类以建立完成...
相关文章推荐
- JAVA游戏编程之二----j2me MIDlet 手机游戏入门开发--扫雷(3)-带线程--仿windows扫雷
- JAVA游戏编程之二----j2me MIDlet 手机游戏入门开发--扫雷(2)-不含线程
- android手机游戏之绘图
- JAVA游戏编程之二----j2me MIDlet 手机游戏入门开发 --扫雷(1)-不含线程
- 基于NFC智能手机(Android)的开发领域 物联网、金融、交通、游戏
- android手机游戏开发Cocos2d-x开发分享
- Android手机游戏开发知识点总结
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》移植到android手机
- Android自定义控件之二 使用path绘图
- 项目回顾之二:PhoneProtector 基于Android平台的手机隐私保护系统
- Android 游戏开发之线程Thread延时开启和停止
- Android手机游戏浅析
- Cocos2dx游戏开发系列笔记9:android手机上运行《战神传说》,并解决横竖屏即分辨率自适应
- 《cocos2d-x手机游戏开发:跨iOS、Android和沃Phone平台》
- 华为手机指定android:installLocation为preferExternal后游戏无法安装
- 探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法
- 探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法
- Android 手机模拟游戏手柄(USB,C#,winio)
- Android游戏开发教程之二:View类与SurfaceView类
- Cocos2d-x 修改Android平台帧率fps - 解决游戏运行手机发热发烫问题