这是我目前在MainActivity.java中的内容。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyBall ball = new MyBall(this);
setContentView(ball);
}
}
这是我的画布类
public class MyBall extends View {
Bitmap myBall;
int gap = 10;
String direction = "down";
float xPos = 0;
float yPos = 0;
public MyBall(Context context) {
super(context);
myBall = BitmapFactory.decodeResource(getResources(), R.drawable.ball3);
}
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(myBall, xPos, yPos, null);
invalidate();
}
}
我希望从左上角,中间右侧,中间左侧,右下方移动,然后再循环回来。当我将方向更改为横向时,我也遇到了问题,因为画布的宽度发生了变化,之后一切都被破坏了。
[编辑]
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
if(direction.equals("down"))
{
if(yPos < canvas.getHeight()/2 - myBall.getWidth()){
xPos+=gap;
yPos+=gap;
}
else {
direction = "up";
Log.d("direction", xPos + "help");
}
}
if(direction.equals("up")){
if (xPos > myBall.getWidth()) {
xPos-=gap;
yPos+=gap;
}
}
canvas.drawBitmap(myBall, xPos, yPos, null);
invalidate();
}
这就是我被困住的地方。球向中间左侧移动,但是当方向改变为横向时,球会下降并且不会上升。
答案 0 :(得分:1)
为了让这个工作变得有效而不会让你的代码变得令人厌恶和混乱,你需要为你的Ball
定义一个好的课程,如果你想添加额外的球,这也增加了灵活性到画布或其他什么。正如您所看到的,我们拥有球实例的所有相关信息,包括方向和颜色,然后我们需要从我们的自定义View
做的就是告诉球移动,并绘制{{ 1}}它包含oval
。
paint
当我们与边界碰撞时,你可能会对我们的计算方式感到困惑。有几种方法,但在我们的例子中,我们正在检查绑定球的矩形是否仍然包含在画布中。 如果不是,这意味着我们已经以某种方式逃过了画布的界限,我们检查了哪个方向需要修改,如果我们已经超过X轴的限制或者在它上面低于零,我们将方向乘以-1,改变修饰符。同样适用于Y轴
上一个类可以包含在一个单独的文件中,也可以包含在自定义View类中,这取决于您和您的编码方式,但对于自定义视图,我们只需要处理绘图:
public class Ball{
public int[] direction = new int[]{1,1}; //direction modifier (-1,1)
public int x,y,size;
public int speed = 10;
public Paint paint;
public RectF oval;
public Ball(int x, int y, int size, int color){
this.x = x;
this.y = y;
this.size = size;
this.paint = new Paint();
this.paint.setColor(color);
}
public void move(Canvas canvas) {
this.x += speed*direction[0];
this.y += speed*direction[1];
this.oval = new RectF(x-size/2,y-size/2,x+size/2,y+size/2);
//Do we need to bounce next time?
Rect bounds = new Rect();
this.oval.roundOut(bounds); ///store our int bounds
//This is what you're looking for ▼
if(!canvas.getClipBounds().contains(bounds)){
if(this.x-size<0 || this.x+size > canvas.getWidth()){
direction[0] = direction[0]*-1;
}
if(this.y-size<0 || this.y+size > canvas.getHeight()){
direction[1] = direction[1]*-1;
}
}
}
}
你真的应该使用public class BouncingBallInside extends View {
private List<Ball> balls = new ArrayList<>();
public BouncingBallInside(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public BouncingBallInside(Context context) {
super(context);
init();
}
private void init(){
//Add a new ball to the view
balls.add(new Ball(50,50,100,Color.RED));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//Draw the balls
for(Ball ball : balls){
//Move first
ball.move(canvas);
//Draw them
canvas.drawOval(ball.oval,ball.paint);
}
invalidate(); // See note
}
}
和设定的间隔来设置动画。但对于一个简单的案例,这应该足够了。
答案 1 :(得分:0)
除了Jaun Cortes之外,还通过引入Arrays在(速度,大小,x和y坐标)中添加了一些随机性
public class BouncingBallInside extends View {
private Ball[] balls = new Ball[10];
/*even new Ball can be added as variable e.g. ballcount passed as new Ball[ballcount] */
public BouncingBallInside(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public BouncingBallInside(Context context) {
super(context);
init();
}
private void init(){
//Add a new ball to the view
for (int i =0; i <10 ; i++) {
balls[i] = (new Ball(i*2,i*5,i*3,i*3 , Color.RED));
// balls.add(new Ball(i*4,i*3,i*2, i*3,Color.GREEN));
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//Draw the balls
for (int i =0; i <10 ; i++) {
balls[i].move(canvas);
//Draw them
canvas.drawOval(balls[i].oval,balls[i].paint);
}
invalidate(); // See note
}
}
然后是球类
public Ball(int x, int y, int s,int size, int color){
this.x = x;
this.y = y;
this.size = size;
this.paint = new Paint();
this.paint.setColor(color);
this.speed =s;
}
public void move(Canvas canvas) {
this.x += speed*direction[0];
this.y += speed*direction[1];
this.oval = new RectF(x-size/2,y-size/2,x+size/2,y+size/2);
//Do we need to bounce next time?
Rect bounds = new Rect();
this.oval.roundOut(bounds); ///store our int bounds
//This is what you're looking for ▼
if(!canvas.getClipBounds().contains(bounds)){
if(this.x-size<0 || this.x+size > canvas.getWidth()){
direction[0] = direction[0]*-1;
}
if(this.y-size<0 || this.y+size > canvas.getHeight()){
direction[1] = direction[1]*-1;
}
}
}
}
和主要活动类别如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final BouncingBallInside bouncingballi = new BouncingBallInside(this);
setContentView(bouncingballi);
}
}