Java 如何每x秒绘制一次位图?

Java 如何每x秒绘制一次位图?,java,android,multithreading,canvas,android-bitmap,Java,Android,Multithreading,Canvas,Android Bitmap,我正在尝试每x秒生成一个新位图(3个可以)。我已经试过了,但都没有用,因为我需要访问canvas参数(您将在代码中看到)。现在,我可以在游戏开始时产生一个精灵,沿着y轴向下移动,就这样。我尝试了一个新线程、一个可运行线程和一个定时器/定时器任务,但由于我的画布需要访问,所以我无法实现其中任何一个 如何每x秒执行一次渲染(画布) 下面是我在GameView(SurfaceView)下的主要活动: import android.app.Activity; import android.content

我正在尝试每x秒生成一个新位图(3个可以)。我已经试过了,但都没有用,因为我需要访问canvas参数(您将在代码中看到)。现在,我可以在游戏开始时产生一个精灵,沿着y轴向下移动,就这样。我尝试了一个新线程、一个可运行线程和一个定时器/定时器任务,但由于我的画布需要访问,所以我无法实现其中任何一个

如何每x秒执行一次渲染(画布)

下面是我在GameView(SurfaceView)下的主要活动:

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Point;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import java.util.Random;

public class MainActivity extends Activity {
    //public static AssetManager assets;
    //public static final int GAME_WIDTH = 800;
    //public static final int GAME_HEIGHT = 450;

    GameView gameView;
    FrameLayout game;
    RelativeLayout widgets;
    ImageButton leftButton;
    ImageButton rightButton;
    ImageButton leftFireButton;
    ImageButton rightFireButton;
    ImageView ship;
    float shipX;
    MediaPlayer mp;
    static final int leftButtonID = 1;
    static final int rightButtonID = 2;
    static final int leftFireButtonID = 3;
    static final int rightFireButtonID = 4;
    //static final int laserId = 5;
    SoundPool soundPool;
    int soundID;
    AsteroidController asteroidController;
    BulletController bulletController;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ship = new ImageView(this);
        gameView = new GameView(this);
        game = new FrameLayout(this);
        widgets = new RelativeLayout(this);
        leftButton = new ImageButton(this);
        rightButton = new ImageButton(this);
        leftFireButton = new ImageButton(this);
        rightFireButton = new ImageButton(this);
        asteroidController = new AsteroidController(this);
        bulletController = new BulletController(this);


        leftButton.setId(leftButtonID);
        rightButton.setId(rightButtonID);
        leftFireButton.setId(leftFireButtonID);
        rightFireButton.setId(rightFireButtonID);
        //laser.setId(laserId);


        leftButton.setImageResource(R.drawable.left_arrow);
        rightButton.setImageResource(R.drawable.right_arrow);
        leftFireButton.setImageResource(R.drawable.red_button);
        rightFireButton.setImageResource(R.drawable.red_button);
        ship.setImageResource(R.drawable.spaceship_1_80x70);


        //add views to screen
        game.addView(gameView);
        game.addView(widgets);
        widgets.addView(leftButton);
        widgets.addView(rightButton);
        widgets.addView(leftFireButton);
        widgets.addView(rightFireButton);
        widgets.addView(ship);
        leftButton.setBackgroundColor(Color.TRANSPARENT);
        rightButton.setBackgroundColor(Color.TRANSPARENT);
        leftFireButton.setBackgroundColor(Color.TRANSPARENT);
        rightFireButton.setBackgroundColor(Color.TRANSPARENT);

        mp = MediaPlayer.create(this, R.raw.bass_loop);
        mp.setLooping(true);
        mp.start();
        loadSounds(this);




       leftButton.setOnTouchListener(new View.OnTouchListener() {
           private Handler handler;

           @Override
           public boolean onTouch(View view, MotionEvent motionEvent) {
               switch(motionEvent.getAction()) {
                   case MotionEvent.ACTION_DOWN:
                       if(handler != null) return true;
                       handler = new Handler();
                       handler.postDelayed(action,50);
                       break;
                       case MotionEvent.ACTION_UP:
                           if(handler == null) return true;
                           handler.removeCallbacks(action);
                           handler = null;
                           break;
               }
               return true;
           }
           Runnable action = new Runnable() {
               @Override public void run() {
                   Display display = getWindowManager().getDefaultDisplay();
                   Point size = new Point();
                   display.getSize(size);
                   //int width = size.x;
                   shipX = ship.getX() - 25;
                   //PREVENT SHIP FROM GOING OFF SCREEN
                   if(shipX <= 0) {
                       leftButton.setClickable(false);
                   } else {
                       leftButton.setClickable(true);
                       ship.setX(shipX);
                       handler.postDelayed(this, 50);
                   }
               }
           };
       });


        rightButton.setOnTouchListener(new View.OnTouchListener() {
            private Handler handler;

            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch(motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        if(handler != null) return true;
                        handler = new Handler();
                        handler.postDelayed(action,50);
                        break;
                    case MotionEvent.ACTION_UP:
                        if(handler == null) return true;
                        handler.removeCallbacks(action);
                        handler = null;
                        break;
                }
                return true;
            }
            Runnable action = new Runnable() {
                @Override public void run() {
                    Display display = getWindowManager().getDefaultDisplay();
                    Point size = new Point();
                    display.getSize(size);
                    int width = size.x;
                    shipX = ship.getX() + 25;
                    //PREVENT SHIP FROM GOING OFF SCREEN
                    if(shipX >= width - 200) {
                        rightButton.setClickable(false);
                    } else {
                        rightButton.setClickable(true);
                        ship.setX(shipX);
                        handler.postDelayed(this, 50);
                    }
                }
            };
        });



        leftFireButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch(motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        //TODO FIRE BULLET....
                        leftFireButton.setClickable(true);
                        bulletController.addBullet(new Bullet((ship.getX() + ship.getWidth() / 2) - 15, ship.getY() + ship.getHeight() / 2, getApplicationContext()));
                        leftFireButton.setBackgroundResource(R.drawable.red_button_pressed);
                        soundPool.play(soundID, 1.0f, 0.5f, 1, 0, 1.0f);

                        return true;
                    case MotionEvent.ACTION_UP:
                        leftFireButton.setBackgroundResource(R.drawable.red_button);
                        //widgets.removeView(laser);
                        return true;
                }

                return false;
            }
        });
        rightFireButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch(motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        //TODO FIRE BULLET                           
                        bulletController.addBullet(new Bullet((ship.getX() + ship.getWidth() / 2) - 15, ship.getY() + ship.getHeight() / 2, getApplicationContext()));
                        rightFireButton.setBackgroundResource(R.drawable.red_button_pressed);
                        soundPool.play(soundID, 1.0f, 0.5f, 1, 0, 1.0f);

                        return true;
                    case MotionEvent.ACTION_UP:
                        rightFireButton.setBackgroundResource(R.drawable.red_button);
                        //widgets.removeView(laser);

                        return true;
                }

                return false;
            }
        });


        //Setup ship
        RelativeLayout.LayoutParams shipParams = new RelativeLayout.LayoutParams(250, 250);

        //Setup a 200 x 200 ImageView for Left Button
        RelativeLayout.LayoutParams leftBtn = new RelativeLayout.LayoutParams(200,200);

        //Setup a 200 x 200 ImageView for Right Button
        RelativeLayout.LayoutParams rightBtn = new RelativeLayout.LayoutParams(200,200);

        //Setup a 200 x 200 ImageView for Left Fire Button
        RelativeLayout.LayoutParams leftFireBtn = new RelativeLayout.LayoutParams(200,200);

        //Setup a 200 x 200 ImageView for Right Fire Button
        RelativeLayout.LayoutParams rightFireBtn = new RelativeLayout.LayoutParams(200,200);

        //Add rules to align the left button programmatically
        leftBtn.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        leftBtn.addRule(RelativeLayout.ALIGN_PARENT_LEFT);

        //Add rules to align the right button programmatically
        rightBtn.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        rightBtn.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);

        //Add rules to align left and right fire buttons
        leftFireBtn.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
        rightFireBtn.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
        leftFireBtn.addRule(RelativeLayout.ABOVE,leftButton.getId());
        rightFireBtn.addRule(RelativeLayout.ABOVE, rightButton.getId());
        leftFireBtn.topMargin = 850;
        rightFireBtn.topMargin = 850;

        shipParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        shipParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
        shipParams.bottomMargin = 100;

        //Now set the params
        leftButton.setLayoutParams(leftBtn);
        rightButton.setLayoutParams(rightBtn);
        leftFireButton.setLayoutParams(leftFireBtn);
        rightFireButton.setLayoutParams(rightFireBtn);
        ship.setLayoutParams(shipParams);

        //Set the content view of the game
        //this.setContentView(new GameView(this));
        this.setContentView(game);
    }

    public void loadSounds(Context context) {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            soundPool = new SoundPool.Builder().setMaxStreams(10).build();
        }
        else {
            soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 1);
        }
        soundID = soundPool.load(context,R.raw.laser,1);
    }


    @Override
    protected void onPause() {
        super.onPause();
        mp.pause();
        gameView.pause();
    }
    @Override
    protected void onResume() {
        super.onResume();
        mp.start();
        gameView.resume();
    }

    public class GameView extends SurfaceView implements Runnable {
        Thread gameViewThread = null;
        SurfaceHolder surfaceHolder;
        boolean okToRun = true;
        //boolean isAlive = true;
        Bitmap star;
        Bitmap three_pixel_star;
        Bitmap stars;
        Asteroid asteroid0;

        public GameView(Context context) {
            super(context);
            //initialize holder
            surfaceHolder = this.getHolder();
            bulletController = new BulletController(context);
            asteroidController = new AsteroidController(context);
            //asteroid_0 = BitmapFactory.decodeResource(getResources(), R.drawable.asteroid_0);
            //asteroid_1 = BitmapFactory.decodeResource(getResources(), R.drawable.asteroid_1);
            //asteroid_2 = BitmapFactory.decodeResource(getResources(),R.drawable.asteroid_2);
            //asteroid0 = new Asteroid(500, -25, context);
            //asteroid1 = new Asteroid(700, -50, context);
            //asteroid2 = new Asteroid(250, -75, context);

        }

        @Override
        public void run() {
            while(okToRun) {
                if(!surfaceHolder.getSurface().isValid()) {
                    continue;
                }
                Canvas gameCanvas = surfaceHolder.lockCanvas();
                customOnDraw(gameCanvas);
                bulletController.tick();
                asteroidController.tick();
                surfaceHolder.unlockCanvasAndPost(gameCanvas);

            }
        }
        protected void customOnDraw(Canvas canvas) {
            Random random = new Random();
            Random random1 = new Random();
            canvas.drawColor(Color.BLACK);
            stars = BitmapFactory.decodeResource(getResources(), R.drawable.stars);
            star = BitmapFactory.decodeResource(getResources(), R.drawable.single_pixel_star);
            three_pixel_star = BitmapFactory.decodeResource(getResources(),R.drawable.three_pixel_star);
            canvas.drawBitmap(star, random1.nextInt(canvas.getWidth()-star.getWidth()),random1.nextInt(canvas.getHeight()-star.getHeight()), null);
            canvas.drawBitmap(three_pixel_star, random.nextInt(canvas.getWidth()-three_pixel_star.getWidth()),random.nextInt(canvas.getHeight()-three_pixel_star.getHeight()), null);
            bulletController.render(canvas);
            asteroid0.render(canvas);
        }
        public void pause() {
            okToRun = false;
            while(true) {
                try {
                    gameViewThread.join();
                } catch(InterruptedException e) {
                    Log.v("ERROR", e.getMessage());
                }
                break;
            }
            gameViewThread = null;
        }
        public void resume() {
            okToRun = true;
            gameViewThread = new Thread(this);
            gameViewThread.start();
        }
    }
}
导入android.app.Activity;
导入android.content.Context;
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Point;
导入android.media.AudioManager;
导入android.media.MediaPlayer;
导入android.media.SoundPool;
导入android.os.Build;
导入android.os.Bundle;
导入android.os.Handler;
导入android.util.Log;
导入android.view.Display;
导入android.view.MotionEvent;
导入android.view.SurfaceHolder;
导入android.view.SurfaceView;
导入android.view.view;
导入android.widget.FrameLayout;
导入android.widget.ImageButton;
导入android.widget.ImageView;
导入android.widget.RelativeLayout;
导入java.util.Random;
公共类MainActivity扩展了活动{
//公共静态资产管理者资产;
//公共静态最终整数游戏宽度=800;
//公共静态最终整数游戏高度=450;
GameView GameView;
框架布局游戏;
相对性窗口小部件;
图像按钮左按钮;
图像按钮右按钮;
ImageButtonLeftFireButton;
ImageButtonRightFireButton;
影像船;
浮船;
MediaPlayer mp;
静态final int leftButtonID=1;
静态最终int rightbutonid=2;
静态final int leftFireButtonID=3;
静态最终int rightFireButtonID=4;
//静态最终int laserId=5;
声池声池;
内部声音ID;
小行星控制器;
子弹控制器子弹控制器;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
ship=新的图像视图(本);
gameView=新gameView(此);
游戏=新框架布局(本);
widgets=新的RelativeLayout(此);
leftButton=新建图像按钮(此按钮);
rightButton=新图像按钮(此按钮);
leftFireButton=新图像按钮(此按钮);
rightFireButton=新图像按钮(此按钮);
asteroidController=新的asteroidController(此);
bulletController=新的bulletController(此);
leftButton.setId(leftButtonID);
rightButton.setId(rightButtonID);
leftFireButton.setId(leftFireButtonID);
rightFireButton.setId(rightFireButtonID);
//激光setId(laserId);
leftButton.setImageResource(R.drawable.left_箭头);
rightButton.setImageResource(R.drawable.right_箭头);
leftFireButton.setImageResource(R.drawable.red_按钮);
rightFireButton.setImageResource(R.drawable.red_按钮);
ship.setImageResource(R.drawable.spaceship_1_80x70);
//将视图添加到屏幕
game.addView(gameView);
addView(小部件);
addView(leftButton);
addView(右按钮);
addView(leftFireButton);
addView(rightFireButton);
addView(ship);
leftButton.setBackgroundColor(颜色.透明);
右按钮。setBackgroundColor(颜色。透明);
leftFireButton.setBackgroundColor(Color.TRANSPARENT);
rightFireButton.setBackgroundColor(颜色.透明);
mp=MediaPlayer.create(这个,R.raw.bass\u循环);
mp.setLooping(真);
mp.start();
装载声音(本);
leftButton.setOnTouchListener(新视图.OnTouchListener(){
私人经办人;
@凌驾
公共布尔onTouch(视图、运动事件、运动事件){
开关(motionEvent.getAction()){
case MotionEvent.ACTION\u DOWN:
if(handler!=null)返回true;
handler=新的handler();
处理程序。后延迟(操作,50);
打破
case MotionEvent.ACTION\u UP:
if(handler==null)返回true;
handler.removeCallbacks(操作);
handler=null;
打破
}
返回true;
}
Runnable action=new Runnable(){
@重写公共无效运行(){
Display Display=getWindowManager().getDefaultDisplay();
点大小=新点();
display.getSize(size);
//int width=size.x;
shipX=ship.getX()-25;
//防止船舶脱离屏幕
如果(shipX=宽度-200){
右按钮。可设置可点击(错误);
}否则{
右按钮。可设置可点击(真);
ship.setX(shipX);
handler.postDelayed(这是50);
}
}
};
});
leftFireButton.setOnTouchListener(新视图.OnTouchListener(){
@凌驾
公共布尔onTouch(视图、运动事件、运动事件){
开关(motionEvent.getAction()){
case MotionEvent.ACTION\u DOWN:
//待办事项射击子弹。。。。
leftFireButton.setClickable(真);
bulletController.addBullet(新项目符号((ship.getX()+ship.getWidth()/2)-15,ship.getY()+ship.getHeight()/2,getApplicationContext());
leftFireButton.setBa
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;

public class Asteroid  {

    private float x, y;
    private Bitmap asteroid0;

    public Asteroid(float x, float y, Context context) {
        this.x = x;
        this.y = y;
        asteroid0 = BitmapFactory.decodeResource(context.getResources(),R.drawable.asteroid_0);
        //asteroid1 = BitmapFactory.decodeResource(context.getResources(),R.drawable.asteroid_1);
        //asteroid2 = BitmapFactory.decodeResource(context.getResources(),R.drawable.asteroid_2);
    }

    public void tick() {
        //MOVE DOWN Y AXIS
        y += 15;

    }
    public void render(Canvas canvas) { //<-- PARAMETER THAT NEEDS ACCESSED

        canvas.drawBitmap(asteroid0, x, y, null); //<-- BECAUSE OF THIS
        this.tick();

    }

    public float getY() {
        return y;
    }
    public float getX() {
        return x;
    }

}
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import java.util.LinkedList;


public class AsteroidController {

   private LinkedList<Asteroid> a = new LinkedList<>();
    Asteroid tempAsteroid;
   Context context;
   float x;
   float y;

   public AsteroidController(Context context) {
       this.context = context;
       this.x = x;
       this.y = y;
       addAsteroid(new Asteroid(x, y, context));
   }
   public void tick() {
       for (int i = 0; i < a.size(); i++) {
           tempAsteroid = a.get(i);

           if (tempAsteroid.getY() > getScreenHeight()) {
               removeAsteroid(tempAsteroid);
           }
           tempAsteroid.tick();
       }
   }

   public static int getScreenHeight() {
       return Resources.getSystem().getDisplayMetrics().heightPixels;
   }
   public static float getScreenWidth() {
       //System.out.println(Resources.getSystem().getDisplayMetrics().widthPixels);
       return Resources.getSystem().getDisplayMetrics().widthPixels;
   }
   //NOT BEING USED AT THE MOMENT
   public void render(Canvas canvas) {
       for(int i = 0; i < a.size(); i++) {
           tempAsteroid = a.get(i);
           //tempAsteroid.render(canvas);
       }
   }
   public void addAsteroid(Asteroid asteroid) {

       a.add(asteroid);
   }
   public void removeAsteroid(Asteroid asteroid) {

       a.remove(asteroid);
   }
}