【问题标题】:calling batch.dispose() gives the fatal signal 11(SIGSEGV) while trying to switch screen尝试切换屏幕时调用 batch.dispose() 会给出致命信号 11(SIGSEGV)
【发布时间】:2017-04-06 12:20:07
【问题描述】:

public class Picasso extends Game {

	public static final String TAG = "debug";

	private Texture blackBar;
	private Texture blackPlayer, redPlayer,greenPlayer, redBar, greenBar;
	private Sound dropSound;
	private Music rainMusic;
	public SpriteBatch batch;
	private OrthographicCamera camera;
	private Rectangle bucket;
	private Array<Rectangle> blackPlayerList,greenPlayerList,redPlayerList;
	private long lastBlackTime,lastRedTime,lastGreenTime;
	private boolean isBlack,isRed,isGreen;

	@Override
	public void create() {
		Gdx.app.setLogLevel(Application.LOG_DEBUG);
		// load the images for the droplet and the bucket, 64x64 pixels each
		batch = new SpriteBatch();
		isBlack = true;
		isGreen = false;
		isRed = false;
		blackBar = new Texture(Gdx.files.internal("bar.png"));
		blackPlayer = new Texture(Gdx.files.internal("player.png"));
		redBar = new Texture(Gdx.files.internal("redBar.png"));
		greenBar = new Texture(Gdx.files.internal("greenBar.png"));
		greenPlayer = new Texture(Gdx.files.internal("greenPlayer.png"));
		redPlayer = new Texture(Gdx.files.internal("redPlayer.png"));

		// create the camera and the SpriteBatch
		camera = new OrthographicCamera();
		camera.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());


		// create a Rectangle to logically represent the bucket
		bucket = new Rectangle();
		bucket.x = Gdx.graphics.getWidth() / 2 - 64 / 2; // center the bucket horizontally
		bucket.y = 20; // bottom left corner of the bucket is 20 pixels above the bottom screen edge
		bucket.width = 6;
		bucket.height = 6;

		// create the blackPlayerList array and spawn the first bar
		blackPlayerList = new Array<Rectangle>();
		redPlayerList = new Array<Rectangle>();
		greenPlayerList = new Array<Rectangle>();
		spawnbar(0);
		spawnRed(150);
		spawnGreen(300);
	}

	private void spawnbar(int gap) {
		Rectangle bar = new Rectangle();
		bar.x = MathUtils.random(0, Gdx.graphics.getWidth()-400);
		bar.y = Gdx.graphics.getHeight()+gap;
		bar.width = 64;
		bar.height = 64;
		blackPlayerList.add(bar);
		lastBlackTime = TimeUtils.millis();
	}

	private void spawnGreen(int gap) {
		Rectangle bar = new Rectangle();
		bar.x = MathUtils.random(0, Gdx.graphics.getWidth()-400);
		bar.y = Gdx.graphics.getHeight()+gap;
		bar.width = 64;
		bar.height = 64;
		greenPlayerList.add(bar);
		lastGreenTime = TimeUtils.millis();
	}

	private void spawnRed(int gap) {
		Rectangle bar = new Rectangle();
		bar.x = MathUtils.random(0, Gdx.graphics.getWidth()-400);
		bar.y = Gdx.graphics.getHeight()+gap;
		bar.width = 64;
		bar.height = 64;
		redPlayerList.add(bar);
		lastRedTime = TimeUtils.millis();
	}

	@Override
	public void render() {
		Gdx.gl.glClearColor(1, 1, 1, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		super.render();
		dispose();
		setScreen(new GameOver(Picasso.this));

		camera.update();

		batch.setProjectionMatrix(camera.combined);

		Gdx.input.setInputProcessor(new InputAdapter(){
			@Override
			public boolean touchDown(int screenX, int screenY, int pointer, int button) {
				if(isBlack){
					isRed = true;
					isBlack = false;
					isGreen = false;
				} else if(isRed){
					isGreen = true;
					isRed = false;
					isBlack = false;
				} else {
					isBlack = true;
					isRed = false;
					isGreen = false;
				}
				return super.touchDown(screenX, screenY, pointer, button);
			}
		});

		// begin a new batch and draw the bucket and
		// all drops
		batch.begin();
		batch.draw(blackPlayer, bucket.x, bucket.y,50,50);
		for(Rectangle bar: blackPlayerList) {
			batch.draw(blackBar, bar.x, bar.y,400,500);
		}
		for(Rectangle bar: redPlayerList) {
			batch.draw(redBar, bar.x, bar.y,400,500);
		}
		for(Rectangle bar: greenPlayerList) {
			batch.draw(greenBar, bar.x, bar.y,400,500);
		}
		if(isBlack){
			batch.draw(blackPlayer, bucket.x, bucket.y,50,50);
		}else if(isGreen){
			batch.draw(greenPlayer, bucket.x, bucket.y,50,50);
		} else{
			batch.draw(redPlayer, bucket.x, bucket.y,50,50);
		}
		batch.end();

		if(Gdx.input.isKeyPressed(Keys.LEFT)) bucket.x -= 200 * Gdx.graphics.getDeltaTime();
		if(Gdx.input.isKeyPressed(Keys.RIGHT)) bucket.x += 200 * Gdx.graphics.getDeltaTime();

		// make sure the bucket stays within the screen bounds
//		if(bucket.x < 0) bucket.x = 0;
//		if(bucket.x > 800 - 64) bucket.x = 800 - 64;
		int rand1=MathUtils.random(1,3);
		int rand2=MathUtils.random(1,3);
		int rand3=MathUtils.random(1,3);
		// check if we need to create a new bar
		if(rand1 == 1){
			if(TimeUtils.millis() - lastBlackTime > 2500) spawnbar(0);
			if(TimeUtils.millis() - lastRedTime > 2500) spawnRed(150);
			if(TimeUtils.millis() - lastGreenTime > 2500) spawnGreen(300);
		} else if(rand1 == 2){
			if(TimeUtils.millis() - lastGreenTime > 2500) spawnGreen(0);
			if(TimeUtils.millis() - lastRedTime > 2500) spawnRed(150);
			if(TimeUtils.millis() - lastBlackTime > 2500) spawnbar(300);
		} else{
			if(TimeUtils.millis() - lastBlackTime > 2500) spawnbar(0);
			if(TimeUtils.millis() - lastGreenTime > 2500) spawnGreen(150);
			if(TimeUtils.millis() - lastRedTime > 2500) spawnRed(300);
		}

		if(rand2 == 1){
			if(TimeUtils.millis() - lastBlackTime > 2500) spawnbar(0);
			if(TimeUtils.millis() - lastGreenTime > 2500) spawnGreen(150);
			if(TimeUtils.millis() - lastRedTime > 2500) spawnRed(300);
		} else if(rand2 == 2){
			if(TimeUtils.millis() - lastBlackTime > 2500) spawnbar(0);
			if(TimeUtils.millis() - lastGreenTime > 2500) spawnGreen(150);
			if(TimeUtils.millis() - lastRedTime > 2500) spawnRed(300);
		} else{
			if(TimeUtils.millis() - lastBlackTime > 2500) spawnbar(0);
			if(TimeUtils.millis() - lastRedTime > 2500) spawnRed(150);
			if(TimeUtils.millis() - lastGreenTime > 2500) spawnGreen(300);
		}

		if(rand3 == 1){
			if(TimeUtils.millis() - lastGreenTime > 2500) spawnGreen(0);
			if(TimeUtils.millis() - lastBlackTime > 2500) spawnbar(150);
			if(TimeUtils.millis() - lastRedTime > 2500) spawnRed(300);
		} else if(rand3 == 2){
			if(TimeUtils.millis() - lastBlackTime > 2500) spawnbar(0);
			if(TimeUtils.millis() - lastRedTime > 2500) spawnRed(150);
			if(TimeUtils.millis() - lastGreenTime > 2500) spawnGreen(300);
		} else{
			if(TimeUtils.millis() - lastGreenTime > 2500) spawnGreen(0);
			if(TimeUtils.millis() - lastBlackTime > 2500) spawnbar(150);
			if(TimeUtils.millis() - lastGreenTime > 2500) spawnGreen(300);
		}

		Iterator<Rectangle> iter = blackPlayerList.iterator();
		while(iter.hasNext()) {
			Rectangle bar = iter.next();
			bar.y -= 200 * Gdx.graphics.getDeltaTime();
			if(bar.y + 210 < 0) iter.remove();
		}

		Iterator<Rectangle> iter2 = redPlayerList.iterator();
		while(iter2.hasNext()) {
			Rectangle bar = iter2.next();
			bar.y -= 200 * Gdx.graphics.getDeltaTime();
			if(bar.y + 210 < 0) iter2.remove();
		}

		Iterator<Rectangle> iter3 = greenPlayerList.iterator();
		while(iter3.hasNext()) {
			Rectangle bar = iter3.next();
			bar.y -= 200 * Gdx.graphics.getDeltaTime();
			if(bar.y + 210 < 0) iter3.remove();
		}
	}

	@Override
	public void dispose() {
		// dispose of all the native resources
		blackBar.dispose();
		greenBar.dispose();
		redBar.dispose();

		blackPlayer.dispose();
		redPlayer.dispose();
		greenPlayer.dispose();

		dropSound.dispose();
		rainMusic.dispose();
		batch.dispose();
	}
}

上面是我的代码,我试图在渲染方法的开头移动到另一个屏幕只是为了尝试切换屏幕,因为我需要稍后在渲染方法中调用它,但它给了我致命的信号 11 时我运行应用程序并停止应用程序,我意识到问题是由 dispose() 中的 batch.dispose() 引起的。

如果我删除了 batch.dispose() 代码,那么应用程序就会运行,但会发生两个屏幕同时运行的情况,即当前屏幕不会消失,而另一个屏幕也开始发挥作用,从而都显示自己的内容.

任何想法,我如何正式切换我的屏幕?

【问题讨论】:

    标签: android libgdx segmentation-fault


    【解决方案1】:

    Game 是应用程序源类。

    dispose() of Game 应该在您退出游戏时调用。不管你在哪个屏幕上render() Game 的方法总是被调用。

    那就这样试试吧:

    创建另一个屏幕(假设是 PlayScreen),就像您的 GameOver 屏幕一样,并将您的渲染方法代码放入该屏幕的渲染方法和 Picasso 类的大部分必需内容中。

    从 Picasso 的 create 方法设置 PlayScreen 到 Game 类的 setScreen(new PlayScreen()) 方法。

    【讨论】:

    • 这一切的意义何在?你只是让我尝试一门新课程吗?
    • 我只是说你做错了事情,因为游戏的渲染方法总是被引擎调用,所以你在处理它们后使用批处理。
    • 如果我在 render 方法的最后写 setScreen 方法会怎样?那么它会起作用吗?
    • 不,你设置屏幕后的想法,Screenrender() 方法调用而不是游戏的render() 方法。不你错了。 Screen 的 render() 方法由 Game 的 render() 方法中的 super.render() 调用。
    【解决方案2】:

    您似乎需要帮助来了解这些方法的作用以及调用它们的时间。 create() 在您的应用程序启动时被调用一次。这本质上是初始化方法。您将在此处加载资源和对象并设置活动的初始状态。这里是调用setScreen(screen) 的地方,设置开始时将显示给用户的屏幕。 render() 方法每帧调用一次(通常每秒调用 60 次)。这是您更新对象并绘制所有内容的地方。但是因为您使用的是 Game 类,所以应该在它们自己的类中实现特定的屏幕,而在 Game 类中,render() 方法只是清除屏幕并调用super.render()dispose() 方法处理资源。只有在您的游戏对免费资源关闭时才应调用此方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-05
      相关资源
      最近更新 更多