1

I'm trying to draw a circle in the application window wherever the user clicks the mouse.

in the below example I draw a circle on the screen at fixed position. That works. Then I try to draw circles based on mouse click coords. The click registers and I can print out the coords on click. The coords are what I expect them to be for wherever I click.

current guesses:

  • the camera (or something else important) isn't wired into the PedigreeInputHandler correctly.
  • something is wrong with the way I'm using screens
  • the circle is being drawn but gets drawn over somehow

I'm not stuck with this implementation strategy if there's a better one.

public class PedigreeInputHandler implements InputProcessor {
     VGame game;

     public PedigreeInputHandler(VGame game){
          this.game = game;
     }

     
     ...

     @Override
     public boolean touchDown(int screenX, int screenY, int pointer, int button) {
          game.shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
          game.shapeRenderer.setColor(Color.BLACK);
          game.shapeRenderer.circle(screenX, screenY, 100);
          System.out.println(screenX);
          System.out.println(screenY);
          game.shapeRenderer.end();
          return false;
     }

     ...

     //other required functions are stubs
}

the PedigreeInputHandler is created in this main VGame class

package com.mygdx.vdna;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import java.util.Random;

public class VGame extends Game {

    public OrthographicCamera camera;
    public ShapeRenderer shapeRenderer;
    public SpriteBatch batch;
    public double width;
    public double height;
    public float [] bgColor = {100, 0, 50};

    // Screens
    public MainMenuScreen mainMenuScreen;
    public GameScreen gameScreen;

    public void create() {
        width = 800;
        height = 480;
        batch = new SpriteBatch();

        camera = new OrthographicCamera();
        shapeRenderer = new ShapeRenderer();

        pedigreeInputHandler = new PedigreeInputHandler(this); // <-- 
        Gdx.input.setInputProcessor(pedigreeInputHandler);

        mainMenuScreen = new MainMenuScreen(this);
        gameScreen = new GameScreen(this);
        this.setScreen(mainMenuScreen); 
    }

    public void render() {
        super.render(); // important!
    }
    

This is the game screen that's showing. The black circle gets drawn correctly


public class GameScreen implements Screen {
    final VGame game;

    public GameScreen(VGame game) {
        this.game = game;
    }

    @Override
    public void render(float delta) {
        ScreenUtils.clear(game.bgColor[0], game.bgColor[1], game.bgColor[2], 1);
        game.shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
        game.shapeRenderer.circle(100,100,100);
        game.shapeRenderer.end();
    }
}

the game starts on a Menu screen defined by this class

public class MainMenuScreen implements Screen {

    final VGame game;

    OrthographicCamera camera;

    public MainMenuScreen(final VGame game) {
        this.game = game;

        camera = new OrthographicCamera();
        camera.setToOrtho(false, (float) game.width, (float)game.height);
    }

    @Override
    public void render(float delta) {
        ScreenUtils.clear(0, 0, 0.2f, 1);

        camera.update();
        game.batch.setProjectionMatrix(camera.combined);

        game.batch.begin();
        game.font.draw(game.batch, "Tap anywhere to begin!", 100, 100);
        game.batch.end();

        if (Gdx.input.isTouched()) {
            game.setScreen(game.gameScreen);
            game.gameScreen.render(0.0F);
            dispose();
        }
    }
     
    ...
    // other required methods are stubs

}
ate50eggs
  • 444
  • 3
  • 14
  • 2
    Shouldn't you do all the drawing in the GameScreen render method? Otherwise, yes it will only be drawn once and written over almost straight away so you'll never see it. When the user clicks to draw a circle, you could add the circle information to a list, and then have the GameScreen render method iterate the list and draw the circles as appropriate. – sorifiend Jul 25 '22 at 00:04

1 Answers1

0

The comment from sorifiend was the solution

Added the circle info to a list in the InputProcessor

     @Override
     public boolean touchDown(int screenX, int screenY, int pointer, int button) {
          float [] circArgs = {screenX, (float) (game.height - screenY), 100};
          game.pedigreeScreen.circlesToRender.add(circArgs);
          return false;
     }

and read from it in the screen's render function

    @Override
    public void render(float delta) {
        ScreenUtils.clear(game.bgColor[0], game.bgColor[1], game.bgColor[2], 1);
        game.shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
        for (float [] c : game.pedigreeScreen.circlesToRender){
            game.shapeRenderer.circle(c[0], c[1], c[2]);
        }
        game.shapeRenderer.end();

    }
ate50eggs
  • 444
  • 3
  • 14