android 2D 游戏的开发的方法

article/2025/10/31 19:32:36

                                 最近学习了android 2D 应用的开发,拿来和大家分享一下,学习2D 开发前我们先了解一下SurfaceView的使用以及贴图技术的使用,最后呢,是一个简单的2的游戏的实现。


 1.SurfaceView的一些用法


                     提供了一个专门的绘图渲染的图形嵌入在一个视图层次;SurfaceView负责将图形正确的显示在屏幕上,访问底层图形是通过SurfaceHolder提供接口,可通过调用getHolder(),图形创建SurfaceView的窗口是可见的;实现方法是surfaceCreated(SurfaceHolder)和surfaceDestroyed(SurfaceHolder)销毁图形

 


                    简单的例子如下

package com.nyist.wj;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Paint.Style;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class SurfaceViewActivity extends Activity {
MySurfaceView mySurfaceView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mySurfaceView = new MySurfaceView(this);
setContentView(mySurfaceView);
}
public class MySurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
SurfaceViewActivity surfaceViewActivity; // Activity的引用
Paint paint; // 画笔的引用
public MySurfaceView(Context context) // 构造器
{
super(context);
this.surfaceViewActivity = (SurfaceViewActivity) context; // 拿到Activity引用
this.getHolder().addCallback(this); // 设置生命周期回调接口的实现者
paint = new Paint(); // 创建画笔
paint.setAntiAlias(true); // 打开抗锯齿
}
@Override
protected void onDraw(Canvas canvas) // onDraw方法
{
paint.setColor(Color.WHITE); // 设置画笔颜色为白色
canvas.drawRect(0, 0, getWidth(), getHeight(), paint); // 绘制白色矩形背景
paint.reset(); // 清除画笔设置
paint.setARGB(50, 0, 255, 0); // 设置画笔颜色和透明度
paint.setStrokeWidth(5); // 设置画笔宽度
RectF rf = new RectF(50, 100, 160, 180); // 创建一个矩形
canvas.drawRect(rf, paint); // 绘制矩形
paint.setARGB(50, 0, 0, 255); // 设置画笔颜色和透明度
paint.setStyle(Style.STROKE); // 设置风格为边框
paint.setStrokeWidth(5); // 设置画笔宽度
Rect r = new Rect(200, 100, 300, 180); // 创建一个矩形
canvas.drawRect(r, paint); // 画一个矩形边框
paint.setColor(Color.RED); // 设置画笔颜色
paint.setAntiAlias(true); // 打开抗锯齿
canvas.drawCircle(100, 250, 30, paint);// 画一个圆
paint.setColor(Color.YELLOW); // 设置画笔颜色
rf = new RectF(200, 250, 300, 300); // 创建一个矩形
canvas.drawOval(rf, paint); // 画一个椭圆,充满矩形
paint.reset(); // 清除画笔设置
paint.setColor(Color.RED); // 设置画笔颜色
paint.setTextSize(40); // 设置文字大小
paint.setStyle(Style.FILL_AND_STROKE);
canvas.drawText("loading...", 50, 350, paint); // 画一个字符串
}
@Override
public void surfaceCreated(SurfaceHolder holder) // 创建时被调用
{
Canvas canvas = holder.lockCanvas(); // 获取画布
try {
synchronized (holder) {
onDraw(canvas);
} // 绘制
} catch (Exception e) {
e.printStackTrace();
} finally {
if (canvas != null) {
holder.unlockCanvasAndPost(canvas);
}
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
} // 继承方法,空实现
@Override
// 继承方法,空实现
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
}
}

实现的效果是:

2.贴图技术的使用

    贴图技术主要包括图片的移动、旋转、透明度、等变化

下面是关于贴图技术的使用方法  首先是自定义的一个布局

 <com.nyist.wj.MysurfaceView
android:id="@+id/mysurfaceview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />

然后就是实现自定义布局引用的类

package com.nyist.wj;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class MysurfaceView extends View {
Bitmap bitmap;
Paint paint;
public MysurfaceView(Context context,AttributeSet attributeSet) {
super(context,attributeSet);
// TODO Auto-generated constructor stub
this.initBitmap();
}
public  void initBitmap() {
// TODO Auto-generated method stub
paint=new Paint();
bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.ball);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
//打开抗锯齿
paint.setAntiAlias(true);
canvas.drawBitmap(bitmap, 50,50,paint);
canvas.save();
Matrix matrix=new Matrix();
//移动
matrix.setTranslate(100, 100);
Matrix matrix2=new Matrix();
//  旋转
matrix2.setRotate(50);
Matrix matrix3=new Matrix();
matrix3.setConcat(matrix, matrix2);
//缩放
matrix.setScale(0.5f, 0.5f);
matrix2.setConcat(matrix3, matrix);
canvas.drawBitmap(bitmap, matrix2, paint);
canvas.restore();
canvas.save();
paint.setAlpha(200);
matrix.setTranslate(150, 150);
//放大
matrix2.setScale(1.3f, 1.3f);
//设置总矩阵
matrix3.setConcat(matrix, matrix2);
canvas.drawBitmap(bitmap, matrix3, paint);
paint.reset();
}
}


实现的效果如下   解释一下:这是横屏显示的结果,左上方是原图片大小  接着是缩放的和放大的图片

3.广告条的实现方法

广告虽不好,但是这确实为android开发者提供了一点微薄的力量,下面就看看广告条的开发

效果图:

实现的过程有自定义的View

<com.nyist.wj.myView
android:layout_width="fill_parent"
android:layout_height="50dip"
/>

实现view的方法

package com.nyist.wj;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class myView extends View {
Bitmap[] bitmap;
int currentindex = 1;
int time = 3000;
boolean isAnima = false;
Paint paint;
int[] imageID;
// 初始化图片数阻
boolean initFlag = false;
float prex, prey;
int xoffset;
public myView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
// TODO Auto-generated constructor stub
this.imageID = new int[] { R.drawable.test1, R.drawable.test2,
R.drawable.test3, R.drawable.test4 };
// 生成图片数组
bitmap = new Bitmap[imageID.length];
paint = new Paint();
// 抗锯齿
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
this.setOnTouchListener(null);
new Thread() {
public void run() {
while (true) {
if (!isAnima) {
currentindex = (currentindex + 1) % imageID.length;
}
// 刷帧重绘
myView.this.postInvalidate();
try {
Thread.sleep(time);
} catch (Exception e) {
// TODO: handthele exception
}
}
};
}.start();
}
public void initBitmap() {
Resources resources = this.getResources();
for (int i = 0; i < imageID.length; i++) {
// ------------------------------
// 实现图片 的缩放
bitmap[i] = scaleChange(BitmapFactory.decodeResource(resources,
imageID[i]
));
}
}
public static Bitmap scaleChange(Bitmap bitmap) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
double xratio = (double) Constant.SCREEN_WIDTH / w;
double yratio = 50.0 / h;
// 生成矩阵
Matrix matrix = new Matrix();
matrix.postScale((float) xratio, (float) yratio);
Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
return result;
}
@Override
public void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
// 第一次运行onDraw方法的时候,调用初始化图片数组的方法
if (!initFlag) {
initBitmap();
initFlag = true;
}
if (canvas == null) {
return;
}
if (!isAnima) {
// -------------------------------------
// 当没有播放动画时候绘制当前图片
drawAD(canvas, xoffset, currentindex);
}
if (isAnima) {
// 当向右滑动时候
if (xoffset > 0) {
int size = imageID.length;
// 得到上一张图片的索引
int preIndex = (currentindex - 1 + size) % size;
// 根据x轴偏移量,算出上一张图片绘制时的x坐标
int nextIndex = xoffset - Constant.SCREEN_WIDTH;
// 绘制当前索引图片
drawAD(canvas, xoffset, (preIndex + 1) % size);
drawAD(canvas, nextIndex, preIndex);
} // 当往左抹时
else if (xoffset < 0) {
int size = imageID.length;
// 得到下一张图片的索引
int preIndex = (currentindex + 1 + size) % size;
int nextIndex = xoffset + Constant.SCREEN_WIDTH;
// 绘制当前图片的索引
drawAD(canvas, xoffset, (preIndex - 1 + size) % size);
drawAD(canvas, nextIndex, preIndex);
}
}
}
public void drawAD(Canvas canvas, int offset, int Index) {
canvas.drawBitmap(bitmap[Index], offset, 0, paint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
prex = x;
prey = y;
System.out.println("------------------------------------");
System.out.println("+++++++++++++++++++++++++++++++++++"
+ currentindex);
return true;
case MotionEvent.ACTION_MOVE:
if (!isAnima && Math.abs(x - prex) > 10) {
isAnima = true;
}
if (isAnima) {
xoffset = (int) (xoffset + x - prex);
prex = x;
prey = y;
}
this.postInvalidate();
return true;
case MotionEvent.ACTION_UP:
if (isAnima) {
if (x < Constant.SCREEN_WIDTH / 4 && xoffset < 0) {
int size = imageID.length;
currentindex = (currentindex + 1) % size;
} else if (x > Constant.SCREEN_WIDTH * 3 / 4 && xoffset > 0) {
int size = imageID.length;
currentindex = (currentindex - 1 + size) % size;
}
}
isAnima = false;
xoffset = 0;
this.postInvalidate();
return true;
}
return false;
}
}


接着是在activity中的插入

package com.nyist.wj;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Window;
import android.view.WindowManager;
public class GuangGaoActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
//        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.main);
DisplayMetrics displayMetrics=new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
Constant.SCREEN_HEIGHT=displayMetrics.heightPixels;	//获取具体的屏幕分辨率数值
Constant.SCREEN_WIDTH=displayMetrics.widthPixels;
}
}

 

4.下面是介绍2D下简单的游戏开发

效果图如下

主要用到的SurfaceView 和贴图技术以及声音的处理

用到的处理方法共有5个类

1.BallGameActivity                        设置屏幕的相关属性

2.GameSurfaceView                    实现显示界面的设置

3.ThreadForDraw                       刷帧线程重新绘制游戏界面

4.ThreadForGo                            控制小球移动

5.ThreadForTimecControl         计算小球运行的时间

下面分别介绍每个类是如何实现的

1.BallGameActivity

package com.nyist.wj;
import java.util.HashMap;
import org.apache.http.auth.AUTH;
import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class BallGameActivity extends Activity {
GameSurfaceView gameSurfaceView;
// 声音缓冲池
SoundPool soundPool;
// 存放声音ID的 map
HashMap<Integer, Integer> soundpoolMap;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 初始化声音
initSounds();
// 设置全屏
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
gameSurfaceView = new GameSurfaceView(this);
setContentView(gameSurfaceView);
// 循环播放音乐
playSound(1, -1);
}
public void playSound(int sound, int loop) {
// TODO Auto-generated method stub
// 播放声音的方法
AudioManager audioManager = (AudioManager) this
.getSystemService(Context.AUDIO_SERVICE);
float streamVolumeMax = audioManager
.getStreamMaxVolume(audioManager.STREAM_MUSIC);
float streamVolumeCurrent = audioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
float volume = streamVolumeCurrent / streamVolumeMax;
// 参数 声音资源的ID 左声道 右声道 优先级 循环次数 回访速度
soundPool.play(soundpoolMap.get(sound), volume, volume, 1, loop, 0.5f);
}
public void initSounds() {
// TODO Auto-generated method stub
// 参数 播放的个数 音频类型 播放的质量
soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
// 创建声音资源的MAP
soundpoolMap = new HashMap<Integer, Integer>();
// 将加载声音的资源 放在map中
soundpoolMap.put(1, soundPool.load(this, R.raw.bg, 1));
}
}


 

2.GameSurfaceView

package com.nyist.wj;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class GameSurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
BallGameActivity ballGameActivity;
ThreadForTimecControl threadForTimecControl;
ThreadForGo threadForGo;
ThreadForDraw threadForDraw;
int backSize = 16; // 背景块大小
int screenWidth = 320; // 屏幕宽度
int screenHeight = 480; // 屏幕高度
int bannerWidth = 40; // 挡板宽度
int bannerHeight = 6; // 挡板高度
int bottomSpance = 16; // 下端留白
int bannerSpan = 5; // 板每次移动的距离
int ballSpan = 8; // 球每次移动的距离
int ballSize = 16; // 小球大小
int hintWidth = 100; // 游戏说明宽度
int hintHeight = 20; // 游戏说明高度
int status = 0; // 游戏状态控制 0-等待开始 1-进行中 2-游戏结束 3-游戏胜利
int score = 0; // 得分
int ballx; // 小球x坐标
int bally; // 小球y坐标
int direction = 0; // 小球方向
int bannerX; // 挡板X坐标
int bannerY; // 挡板Y坐标
int scoreWidth = 32;
Bitmap iback; // 背景图
Bitmap[] iscore = new Bitmap[10];// 得分图
Bitmap iball; // 小球用图
Bitmap ibanner; // 挡板用图
Bitmap ibegin; // 开始用图
Bitmap igameover; // 游戏结束用图
Bitmap iwin; // 游戏结束用图
Bitmap iexit; // 退出用图
Bitmap ireplay; // 重玩用图
public GameSurfaceView(BallGameActivity ballGameActivity) {
super(ballGameActivity);
// 注册回调接口
getHolder().addCallback(this);
this.ballGameActivity = ballGameActivity;
initBitmap();
// /----------------------------------------------
threadForDraw = new ThreadForDraw(this);
// TODO Auto-generated constructor stub
}
public void initBitmap() {
iback = BitmapFactory.decodeResource(getResources(), R.drawable.back);
iscore[0] = BitmapFactory.decodeResource(getResources(), R.drawable.d0);
iscore[1] = BitmapFactory.decodeResource(getResources(), R.drawable.d1);
iscore[2] = BitmapFactory.decodeResource(getResources(), R.drawable.d2);
iscore[3] = BitmapFactory.decodeResource(getResources(), R.drawable.d3);
iscore[4] = BitmapFactory.decodeResource(getResources(), R.drawable.d4);
iscore[5] = BitmapFactory.decodeResource(getResources(), R.drawable.d5);
iscore[6] = BitmapFactory.decodeResource(getResources(), R.drawable.d6);
iscore[7] = BitmapFactory.decodeResource(getResources(), R.drawable.d7);
iscore[8] = BitmapFactory.decodeResource(getResources(), R.drawable.d8);
iscore[9] = BitmapFactory.decodeResource(getResources(), R.drawable.d9);
iball = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
ibanner = BitmapFactory.decodeResource(getResources(),
R.drawable.banner);
ibegin = BitmapFactory.decodeResource(getResources(), R.drawable.begin);
igameover = BitmapFactory.decodeResource(getResources(),
R.drawable.gameover);
iwin = BitmapFactory.decodeResource(getResources(), R.drawable.win);
iexit = BitmapFactory.decodeResource(getResources(), R.drawable.exit);
ireplay = BitmapFactory.decodeResource(getResources(),
R.drawable.replay);
// 初始化小球位置及板X坐标
initBallAndBanner();
}
public void initBallAndBanner() {
// 初始化小球位置
bally = screenHeight - bottomSpance - bannerHeight - ballSize;
ballx = screenWidth / 2 - ballSize / 2;
// 初始化板X坐标
bannerX = screenWidth / 2 - bannerWidth / 2;
bannerY = screenHeight - bottomSpance - bannerHeight;
}
public void replay() {
if (status == 2 || status == 3) {
// 初始化小球的位置
initBallAndBanner();
score = 0;
status = 0;
direction = 3;
}
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
// 清除背景
int colum = screenWidth / backSize
+ ((scoreWidth % backSize == 0) ?0:1);
int rows = screenHeight / backSize
+ ((screenHeight % backSize == 0) ? 0 : 1);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < colum; j++) {
canvas.drawBitmap(iback, 16*j, 16*i, null);
}
}
// 绘制得分
String scorestr = score + "";
int loop = 3 - scorestr.length();
for (int i = 0; i < loop; i++) {
scorestr = "0" + scorestr;
}
int startX = screenWidth - scoreWidth * 3 - 10;
for (int i = 0; i < 3; i++) {
int tempScore = scorestr.charAt(i) - '0';
canvas.drawBitmap(iscore[tempScore], startX + i * scoreWidth, 5,
null);
}
// 绘制小球
canvas.drawBitmap(iball, ballx, bally, null);
// 绘制板
canvas.drawBitmap(ibanner, bannerX, bannerY, null);
// 绘制开始提示
if (status == 0) {
canvas.drawBitmap(ibegin, screenWidth / 2 - hintWidth / 2,
screenHeight / 2 - hintHeight / 2, null);
}
// 绘制失败提示
if (status == 2) {
canvas.drawBitmap(igameover, screenWidth / 2 - hintWidth / 2,
screenHeight / 2 - hintHeight / 2, null);
}
// 绘制胜利提示
if (status == 3) {
canvas.drawBitmap(iwin, screenWidth / 2 - hintWidth / 2,
screenHeight / 2 - hintHeight / 2, null);
}
// 绘制退出提示
canvas.drawBitmap(iexit, screenWidth - 32, screenHeight - 16, null);
// /绘制重玩提示
if (status == 2 || status == 3) {
canvas.drawBitmap(ireplay, 0, screenHeight - 16, null);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
if (x < screenWidth && x > screenWidth - 32 && y < screenHeight
&& y > screenHeight - 16) {
// ----------------------------------------------------------
// 按下退出选项退出系统
ballGameActivity.soundPool.stop(1);
System.exit(0);
}
// 等待状态
if (status == 0) {
status = 1;
// ----------------------------------------------
threadForTimecControl = new ThreadForTimecControl(this);
threadForGo = new ThreadForGo(this);
threadForTimecControl.start();
threadForGo.start();
} else if (status == 1) {
bannerX = x;
} else if (status == 2 || status == 3) {
if (x < 32 && x > 0 && y < screenHeight && y > screenHeight - 16) {
//按下重玩
replay();
}
}
// TODO Auto-generated method stub
return super.onTouchEvent(event);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
// ----------------------------------
// 创建时候启动相关进程
this.threadForDraw.flag = true;
threadForDraw.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// 释放相应的进程
boolean retry = true;
this.threadForDraw.flag = false;
// 不断的循环知道刷帧结束
while (retry) {
try {
threadForDraw.join();
retry = false;
} catch (InterruptedException e) {
// TODO: handle exception
}
}
}
}


 

3.ThreadForDraw

package com.nyist.wj;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
public class ThreadForDraw extends Thread {
boolean flag=true;
int sleep=100;
GameSurfaceView gameSurfaceView;
SurfaceHolder surfaceHolder;
public ThreadForDraw (GameSurfaceView gameSurfaceView){
this.gameSurfaceView=gameSurfaceView;
this.surfaceHolder=gameSurfaceView.getHolder();
}
@Override
public void run() {
// TODO Auto-generated method stub
Canvas canvas;
while (this.flag) {
canvas=null;
try {
canvas=this.surfaceHolder.lockCanvas(null);
synchronized (this.surfaceHolder) {
gameSurfaceView.onDraw(canvas);
}
} catch (Exception e) {
}finally{
if (canvas!=null) {
this.surfaceHolder.unlockCanvasAndPost(canvas);
}
}
try {
Thread.sleep(sleep);
} catch (Exception e) {
// TODO: handle exception
}
}
super.run();
}
}


 

4.ThreadForGo

package com.nyist.wj;
//游戏过程中移动小球的线程
public class ThreadForGo extends Thread {
// 设置线程执行的标志
boolean flag = true;
// 游戏界面的引用
GameSurfaceView gameSurfaceView;
public ThreadForGo(GameSurfaceView gameSurfaceView) {
this.gameSurfaceView = gameSurfaceView;
}
@Override
public void run() {
// TODO Auto-generated method stub
while (flag) {
switch (gameSurfaceView.direction) {
case 0:
// 右上控制当前方向移动球
gameSurfaceView.ballx = gameSurfaceView.ballx
+ gameSurfaceView.ballSpan;
gameSurfaceView.bally = gameSurfaceView.bally
- gameSurfaceView.ballSpan;
// 判断是否碰壁
if (gameSurfaceView.ballx >= gameSurfaceView.screenWidth
- gameSurfaceView.ballSize) {
// 碰到上壁
gameSurfaceView.direction = 3;
} else if (gameSurfaceView.bally <= 0) {
gameSurfaceView.direction = 1;
}
break;
case 1:
// 右下
gameSurfaceView.ballx = gameSurfaceView.ballx
+ gameSurfaceView.ballSpan;
gameSurfaceView.bally = gameSurfaceView.bally
+ gameSurfaceView.ballSpan;
// 碰到下壁
if (gameSurfaceView.bally >= gameSurfaceView.screenHeight
- gameSurfaceView.bannerHeight
- gameSurfaceView.bottomSpance
- gameSurfaceView.ballSize) {
// /-----------------------------------------
checkCollision(1);
// 碰到右臂
} else if (gameSurfaceView.ballx >= gameSurfaceView.screenWidth
- gameSurfaceView.ballSize) {
gameSurfaceView.direction = 2;
}
break;
case 2:
// 左下
gameSurfaceView.ballx = gameSurfaceView.ballx
- gameSurfaceView.ballSpan;
gameSurfaceView.bally = gameSurfaceView.bally
+ gameSurfaceView.ballSpan;
// 碰到下壁
if (gameSurfaceView.bally >= gameSurfaceView.screenHeight
- gameSurfaceView.bannerHeight
- gameSurfaceView.bottomSpance
- gameSurfaceView.ballSize) {
// -----------------------------------
checkCollision(2);
}
// 碰到左壁
else if (gameSurfaceView.ballx <= 0) {
gameSurfaceView.direction = 1;
}
break;
case 3:
gameSurfaceView.ballx = gameSurfaceView.ballx
- gameSurfaceView.ballSpan;
gameSurfaceView.bally = gameSurfaceView.bally
- gameSurfaceView.ballSpan;
// /碰到左壁
if (gameSurfaceView.ballx <= 0) {
gameSurfaceView.direction = 0;
}
// 碰到上壁
else if (gameSurfaceView.bally <= 0) {
gameSurfaceView.direction = 2;
}
break;
default:
break;
}
try {
Thread.sleep(100);
} catch (Exception e) {
// TODO: handle exception
}
}
}
public void checkCollision(int dirction) {
if (gameSurfaceView.ballx >= gameSurfaceView.bannerX
- gameSurfaceView.ballSize
&& gameSurfaceView.ballx <= gameSurfaceView.bannerX
+ gameSurfaceView.bannerWidth) {
switch (dirction) {
case 1:
gameSurfaceView.direction = 0;
break;
case 2:
gameSurfaceView.direction = 3;
break;
default:
break;
}
} else {
// 没有碰到板
gameSurfaceView.threadForTimecControl.flag = false;
gameSurfaceView.threadForGo.flag = false;
gameSurfaceView.status = 2;
}
}
}


 

 

 5.ThreadForTimecControl

 

package com.nyist.wj;
public class ThreadForTimecControl extends Thread {
//计算生存时间的线程
//判断是否胜利的值
int highest = 200;
//	游戏界面的引入
GameSurfaceView gameSurfaceView;
//线程标志位
boolean flag = true;
public ThreadForTimecControl(GameSurfaceView gameSurfaceView) {
this.gameSurfaceView = gameSurfaceView;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(flag){
gameSurfaceView.score++;
if (gameSurfaceView.score==highest) {
//游戏胜利
gameSurfaceView.status=3;
//----------------------------------------
gameSurfaceView.threadForTimecControl.flag=false;
gameSurfaceView.threadForGo.flag=false;
}
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
}
}
}
}



 

ps:个人总结

小球的初始位置确定

代码是

	// 初始化小球位置
bally = screenHeight - bottomSpance - bannerHeight - ballSize;
ballx = screenWidth / 2 - ballSize / 2;
// 初始化板X坐标
bannerX = screenWidth / 2 - bannerWidth / 2;
bannerY = screenHeight - bottomSpance - bannerHeight;


 

 


http://chatgpt.dhexx.cn/article/eGbkMK6g.shtml

相关文章

Android手机游戏开发入门教程

Android手机游戏开发入门教程 视频欣赏地址 来自 “ ITPUB博客 ” &#xff0c;链接&#xff1a;http://blog.itpub.net/29597077/viewspace-1139520/&#xff0c;如需转载&#xff0c;请注明出处&#xff0c;否则将追究法律责任。 转载于:http://blog.itpub.net/29597077/vie…

Android 游戏开发速递

作者 / Greg Hartrell, Head of Product Management, Games on Android & Google Play 在今年 3 月举行的 Google 游戏开发者峰会上&#xff0c;我们分享了 Google 为帮助游戏开发者而持续投入研发的数种新工具和服务。这些新工具和服务能够帮助游戏开发者更轻松地查看其 A…

游戏开发相关

游戏开发—图形图像篇 游戏开发--开篇  记得我第一次玩的PC game 是KKND(绝地风暴)&#xff0c;当时的游戏平台是DOS&#xff0c;我只是觉得很好玩&#xff0c;经常和几个小学同学一起厮杀到12点。可是现在回忆起来&#xff0c;KKND无论是从智能设计还是在游戏画面与操作上都…

android小游戏制作基础,View实现游戏布局和方法

在使用android的朋友们&#xff0c;相信大家对android的游戏不陌生吧&#xff0c;像愤怒的小鸟&#xff0c;植物大战僵尸等等优秀的游戏&#xff0c;给我们带来了很好的用户体验 下面我来教大家一点android游戏开发的一点基础&#xff0c;大家可以参照这个方法框架来设计一些像…

android游戏开发的架构

&#xfeff;&#xfeff; 在编写游戏代码之前&#xff0c;必须要仔细地理顺思路&#xff0c;清晰地构建出整个游戏的框架。有的开发者经常抱怨说&#xff0c;游戏开发到最后总是千头万绪&#xff0c;一旦出现bug就不知道该如何修改&#xff0c;身心疲惫甚至是痛不欲生。其实不…

用Unity3d开发Android游戏

Unity3d是个强大的游戏引擎&#xff0c;可以很轻松的将游戏发布到Android平台上&#xff0c;今天我就来讲讲如何用Android来开发Android游戏。 首先我们要下载Android SDK&#xff0c;可以在http://developer.android.com/sdk/index.html这里下载到&#xff0c;运行installer安…

Android游戏开发的入门实例

在Android系统上开发游戏是Android开发学习者所向往的&#xff0c;有成就感也有乐趣&#xff0c;还能取得经济上的报酬。那怎样开发Android游戏呢&#xff1f;下面介绍一个简单的入门实例。 一、创建新工程   首先&#xff0c;我们在Eclipse中新建一个名为Movement的工程&…

如何开发手机游戏?

当今社会&#xff0c;手机游戏无非是当下在旅途中打发时间的最便捷的方式。有关数据显示&#xff0c;62% 的智能手机用户在购买智能手机后的一周内安装了游戏。无论你是参加聚会还是度假&#xff0c;或者周末宅在家里&#xff0c;手机都是玩游戏最方便的设备。这也正是手机游戏…

【Android游戏开发详细过程1】Android平台飞机大战游戏APP设计与实现

【Android游戏】Android平台飞机大战游戏APP设计与实现 前言一、界面设计与功能实现1.1 主界面1.2 登录界面1.2 注册界面1.4 菜单界面1.5 设置界面1.6 商店界面1.7 换机界面1.8 游戏界面1.9 欢迎界面1.10 游戏图标 二、数据库设计与实现三、服务器设计与实现四、其他功能实现 前…

datagridview中使用DataGridViewComboBoxColumn

在datagridview中使用自带的DataGridViewComboBoxColumn&#xff0c;加载数据库中的数据&#xff0c;选中和保存所需要的数据 实现效果如图 加载数据库已保存的数 选择自己所需要的数据 具体代码如下 datagridview命名为&#xff1a;dgvDrugList 添加基本列及对应的设…

DataGridView怎样实现添加、删除、上移、下移一行

场景 在Winform中使用DataGridView实现添加一行、删除一行、上移一行、下移一行。 注&#xff1a; 博客主页&#xff1a;https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书、教程推送与免费下载。 实现 添加一行 private void Task…

DataGridview获取选中行数

DataGridview获取选中行数 代码&#xff1a; dataGridView1.CurrentRow.Index//获取选中行数使用Messbox.Show()弹窗&#xff1a;

DataGridview动态初始化

DataGridview动态初始化 this.dataGridView1.Rows.Add("参数"&#xff0c;"参数"...");Add&#xff08;&#xff09;方法里面可以根据列数而添加相应个数的参数 例如&#xff1a; 上图的列数有4个&#xff0c;所以如果要将DataGridview控件里面添加…

C# 解决datagridview控件显示大量数据拖拉卡顿问题

问题描述&#xff1a; 由于在使用SQL查询大量的数据并一次显示到dataGridView控件&#xff0c;出现拖拉的时候卡顿。 解决方法&#xff1a; 1.首先分页。 2.其次把显示控件设置双buffer。 解决过程如下&#xff1a; 1.设置dataGridView双buffer代码如下&#xff0c;需要引用…

DataGridView绑定数据库

背景 今天在做C#实验的时候&#xff0c;遇到了一个难题&#xff1a;需要将数据库中的数据在C#的窗体的DataGridView控件中显示出来。当然老师布置这个作业是在之前做了铺垫的&#xff0c;之前做省县区三级查询时&#xff0c;讲过了SampleData和LiteDB的使用&#xff0c;但是我…

Winform实现在DataGridView控件的单元格中添加多个控件

Winform实现在DataGridView控件的单元格中添加多个控件 背景实现思路关键代码完整代码下载 背景 DataGridView控件的列是支持TextBoxColumn、ComboBoxColumn等类型的&#xff0c;就是DataGridView的单元格进入编辑模式的时候就会出现对应的控件&#xff0c;但是有些业务场景是…

C# datagridview 单行文字自动换行

dgv.DefaultCellStyle.WrapMode True dgv.RowTemplate.DefaultCellStyle.WrapMode True dgb.RowsDefaultCellStyle.WrapMode True dgv.AlternatingRowsDefaultCellStyle.WrapMode True 在设计界面里手动设置&#xff0c;一般情况下&#xff0c;设置其中一个WrapMode为true…

c#提高datagridview刷新速度(两种方法计时对比)

两种方法&#xff0c;代码如下&#xff1a; void initDataGridView(){Stopwatch sw new Stopwatch();//Stopwatch提供一组方法和属性&#xff0c;可用于准确地测量运行时间sw.Start();//方法一&#xff1a;一行一行增加到datagridview中for (int i 0; i < 10000; i){int R…

Winform中打印 dataGridView里的内容

最近评论问题比较多&#xff0c;这是几年前得代码了&#xff0c;今天正好有时间我重新整理了下代码把源码Demo发上来给大家看看互相学习。 有问题随时交流。没有积分得私信我发你。 Demo地址&#xff1a;DataGirdView打印.rar-C#文档类资源-CSDN下载 //调用GridPrinter首先添…

C# DataGridView 使用

1、//dataGridView標題居中 dataGridView2.ColumnHeadersDefaultCellStyle.Alignment DataGridViewContentAlignment.MiddleCenter;2、//dataGrideView文本居中 dataGridView2.RowsDefaultCellStyle.Alignment DataGridViewContentAlignment.MiddleCenter;3、//dataGridVie…