how to draw images from another class in android? - java

I am new to android graphics as far as custom views and such. I have the following program, but the SurfaceView for some reason will not draw a image from an object of another class. I continue to get a null pointer exception.
MAIN CLASS:
public class Main extends Activity {
MyView view;
TestObject test;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
view = new MyView(this, this);
test = new TestObject(this);
setContentView(view);
}
public TestObject getTest() {
return test;
}
public void setTest(TestObject test) {
this.test = test;
}
}
VIEW CLASS:
public class MyView extends SurfaceView implements Runnable {
SurfaceHolder surfaceHolder;
Thread thread;
TestObject test;
public MyView(Context context, Main main) {
super(context);
this.test = main.getTest();
surfaceHolder = getHolder();
thread = new Thread(this);
thread.start();
}
#Override
public void run() {
while(true){
if(!surfaceHolder.getSurface().isValid())
continue;
Canvas canvas = surfaceHolder.lockCanvas();
canvas.drawBitmap(test.getImage(), test.getX(), test.getY(), null);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
OBJECT CLASS:
public class TestObject {
Main main;
Bitmap image;
int x,y;
DisplayMetrics dm;
public TestObject(Main main) {
this.main = main;
image = BitmapFactory.decodeResource(main.getResources(), R.drawable.ic_launcher);
dm = new DisplayMetrics();
x = dm.widthPixels / 2;
y = dm.heightPixels / 2;
}
public Bitmap getImage() {
return image;
}
public void setImage(Bitmap image) {
this.image = image;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
I get a null pointer exception at canvas.drawBitmap(test.getImage(), test.getX(), test.getY(), null); in the MyView class. Strangly, it will work if if was to say canvas.drawBitmap(BitmapFactory.decodeResource(main.getResources(), R.drawable.ic_launcher), 0, 0, null); (or any other x, y position).
Any help is appreciated!

You should override "onDraw" method of "MyView" instead of implementing Runnable.

Related

Accessing to inner class in java

I'm a beginner in libGdx and I'm making a simple game.
I wrote a nested class. As you can see here:
public class classes{
public class GameObject{
//declaring section
private Texture texture;
private Texture[] spawnAnimation;
private Texture[] deathAnimation;
private Texture[] damageAnimation;
private Texture[] moveAnimation;
private Texture[] fightAnimation;
private Texture[] talkAnimation;
private SpriteBatch batch = new SpriteBatch();
private float width, height;
private float x, y;
private Sound spawnSound, touchSound, deathSound, objSound, moveSound, fightSound;
public GameObject(Texture txtr, float width, float height, float x, float y) {
this.texture = txtr;
this.width = width;
this.height = height;
this.x = x;
this.y = y;
}
//this method checks wether our game object is over an other object
public boolean isOver(GameObject obj){
if(((this.x >= obj.x) && (this.x <= (obj.x + obj.width))) && ((this.y >= obj.y) && (this.y <= (obj.y + obj.height))))
return true;
return false;
}
//this method sets the object bounds
public void setBounds(float width, float height, float x, float y){
this.width = width;
this.height = height;
this.x = x;
this.y = y;
}
//this method draws the object
public void draw(){
batch.draw(this.texture, this.width, this.height, this.x, this.y);
}
//animation setting section
public void setSpawnAnimation(Texture[] texture){
this.spawnAnimation = texture;
}
public void setDeathAnimation(Texture[] texture){
this.deathAnimation = texture;
}
public void setDamageAnimation(Texture[] texture){
this.damageAnimation = texture;
}
public void setMoveAnimation(Texture[] texture){
this.moveAnimation = texture;
}
public void setFightAnimation(Texture[] texture){
this.fightAnimation = texture;
}
public void setTalkAnimation(Texture[] texture){
this.talkAnimation = texture;
}
//sounds setting section
public void setSpawnSound(Sound sound){
this.spawnSound = sound;
}
public void setTouchSound(Sound sound){
this.touchSound = sound;
}
public void setDeathSound(Sound sound){
this.deathSound = sound;
}
public void setObjSound(Sound sound){
this.objSound = sound;
}
public void setMoveSound(Sound sound){
this.moveSound = sound;
}
public void setFightSound(Sound sound){
this.fightSound = sound;
}
//animation and behavior section
public void spawn(){
batch.begin();
for(int i=0;i<=this.spawnAnimation.length;i++){
this.texture = this.spawnAnimation[i];
this.draw();
try
{
Thread.sleep(0, 1);
}
catch (InterruptedException e)
{}
}
batch.end();
}
public void die(Texture[] deathTexture){
}
}
}
I went to the other file, in the other class, and I tried to set the object texture
public class MyGdxGame implements ApplicationListener{
Texture texture;
SpriteBatch batch;
classes.GameObject gun;
#Override
public void create()
{
batch = new SpriteBatch();
gun = new classes.GameObject(new Texture(Gdx.files.internal("gun.png")), 0, 0, 300, 300);
}
#Override
public void render()
{
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.end();
}
#Override
public void dispose()
{
}
#Override
public void resize(int width, int height)
{
}
#Override
public void pause()
{
}
#Override
public void resume()
{
}
}
once I try to access it. I face this error: aan instance for an enclosing class is required
note: I'm making this game for android. using AIDE ide which offers developing apps and games directly on your phone.
Inner classes that are declared without the keyword static are tethered to the outer class they exist in.
To fix
public static class GameObject{
Why would you want an inner class without static? Here's an example
public class Game {
private Data gameData;
class MyListener {
public void receiveNewData(Data newData) {
//update gameData with the new data
}
}
}
If MyListener was static, it would not be able to access Game's gameData

How to access the same instance from multiple classes

I'm trying to access the same instance of a class from multiple classes.
I have a class for my turret and I'm trying to draw the turret using my View class and, at the same time, update its location using my logic class. I don't understand how to check if the class already has a running instance and if it does how to access the running instance. I can't find anything online I understand and it's going right over my head, all help is appreciated!
Turrets
public class Turrets {
int health, x, y, speed;
Bitmap sprite;
public Turrets (Context context){ }
public void isMoving(){
x += speed;
}
public int getHealth() {return health;}
public int getX() {return x;}
public int getY() {return y;}
public Bitmap getSprite() {return sprite;}
}
SimpleTurret
public class SimpleTurret extends Turrets {
public SimpleTurret(Context context){
super(context);
sprite = BitmapFactory.decodeResource(context.getResources(), R.drawable.test_sprite);
health = 50;
x = 300;
y = 100;
speed = 1;
}
}
Logic
public class Logic implements Runnable{
Boolean isRunning;
private Thread logicThread;
SimpleTurret simpleTurret;
public Logic(Context context, boolean running){
simpleTurret = new SimpleTurret(context);
logicThread = new Thread(this);
logicThread.start();
isRunning = running;
}
#Override
public void run() {
while (isRunning){
gameView.rapidFireTurret.isMoving();
}
}
}
GameView
public class GameView extends SurfaceView implements Runnable {
private boolean running = true;
SurfaceHolder surfaceHolder = getHolder();
SimpleTurret simpleTurret;
RapidFireTurret rapidFireTurret;
public GameView (Context context){
super(context);
Thread thread = new Thread(this);
thread.start();
}
#Override
public void run() {
while (running){
DrawCanvas();
}
}
public void DrawCanvas(){
Canvas canvas = surfaceHolder.lockCanvas();
if (surfaceHolder.getSurface().isValid()){
canvas.drawColor(Color.RED);
canvas.drawBitmap(simpleTurret.getSprite(), simpleTurret.getX(), simpleTurret.getY(), null);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
Use Singleton like class.
// Java program implementing Singleton class
// with getInstance() method
class Singleton {
// static variable single_instance of type Singleton
private static Singleton single_instance_first = null;
private static Singleton single_instance_second = null;
private static Singleton single_instance_third = null;
// variable of type String
public String s;
// private constructor restricted to this class itself
private Singleton() {
s = "Hello I am a string part of Singleton class";
}
// static method to create instance of Singleton class
public static Singleton getInstance(int index) {
switch (index) {
case 0: {
if (single_instance_first == null)
single_instance_first = new Singleton();
return single_instance_first;
}
case 1: {
if (single_instance_second == null)
single_instance_second = new Singleton();
return single_instance_second;
}
case 2: {
if (single_instance_third == null)
single_instance_third = new Singleton();
return single_instance_third;
}
default: {
if (single_instance_first == null)
single_instance_first = new Singleton();
return single_instance_first;
}
}
}
}
and use
Singleton firstSingleton = Singleton.getInstance(0);
Singleton secondSingleton = Singleton.getInstance(1);
Singleton thirdSingleton = Singleton.getInstance(2);
Change your class to this
public class Turrets {
int health, x, y, speed;
Bitmap sprite;
static Singleton mInstance;
Context mContext;
public Turrets (Context context){
this.mContext=context;
}
public void isMoving(){
x += speed;
}
public int getHealth() {return health;}
public int getX() {return x;}
public int getY() {return y;}
public Bitmap getSprite() {return sprite;}
public static Turrets getInstance()
{
if (mInstance == null) {
mInstance = new Turrets(mContext);
}else {
return mInstance;
}
}
}

Getters returning null from activity class

I've spent a lot of time today researching why my getters are returning null and cant seem to find a clean answer. I am looking to create a clean hierarchy using classes and pass the information from one to the other. I dont know if this is good practice im still new to game development and android studio in general. I would like to be able to pass the variables from the Game.java(which is my activity class) without adding it to my other classes in their constructors. I want to be able to access the getters like it is another class but cant seem to work out how. Full code will be included below: getXDirection and getyDirecion in the Game.java are returning 0 from the player class which implys they haven't been initialised
Game.java
package com.Frenchie.SpaceshipSammy;
import ...
public class Game extends Activity implements SensorEventListener{
private SensorManager senSensorManager;
private Sensor senAccelerometer;
//Directional constants
private static final int DIRECTION_STATIONARY = 0;
private static final int DIRECTION_LEFT = 1;
private static final int DIRECTION_RIGHT= 2;
private static final int DIRECTION_UP = 3;
private static final int DIRECTION_DOWN= 4;
//Direction variables
private int yDirection, xDirection;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Set view to GameView
setContentView(new GameView(this));
//Sensor stuff
senSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
senAccelerometer = senSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
senSensorManager.registerListener(this, senAccelerometer , SensorManager.SENSOR_DELAY_GAME);
}
#Override
public boolean onTouchEvent(MotionEvent motionEvent) {
switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
//Finger down - Move up
yDirection = DIRECTION_UP;
break;
case MotionEvent.ACTION_UP:
//Finger lifted - Move down
yDirection = DIRECTION_DOWN;
break;
}
return true;
}
//Overriding Accelerometer to read data
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
Sensor mySensor = sensorEvent.sensor;
if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) {
float x = sensorEvent.values[1];
if (x > -1 && x < 1) {
//Stationary
xDirection = DIRECTION_STATIONARY;
} else if (x >= 1) {
//Move right
xDirection = DIRECTION_RIGHT;
} else if (x <= -1) {
//Move left
xDirection = DIRECTION_LEFT;
} else {
Log.d("onSensorChanged", "Escaped");
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
//Getters for Player class to use
public int getyDirection() {
return yDirection;
}
public int getxDirection() {
return xDirection;
}
}
Player.java
package com.Frenchie.SpaceshipSammy;
import ...
public class Player {
//Directional constants
private static final int DIRECTION_STATIONARY = 0;
private static final int DIRECTION_LEFT = 1;
private static final int DIRECTION_RIGHT = 2;
private static final int DIRECTION_UP = 3;
private static final int DIRECTION_DOWN = 4;
//Location variables
private int x, y, speed;
//Sprite
private Bitmap sprite;
private Game userInput;
public Player(Context context){
speed = 10;
userInput = new Game();
sprite = BitmapFactory.decodeResource(context.getResources(), R.drawable.player);
}
//Called from Logic to move players location
public void PositionUpdate(){
xMove();
yMove();
}
private void xMove(){
if (userInput.getxDirection() == DIRECTION_STATIONARY){
//Stationary
}
else if (userInput.getxDirection() == DIRECTION_RIGHT){
//Move right
x += speed;
Log.d("xMove","Right");
}
else if (userInput.getxDirection() == DIRECTION_LEFT){
//Move left
x -= speed;
}
else {
Log.d("xMove", "xDirection unrecognised");
}
}
private void yMove(){
if (userInput.getyDirection() == DIRECTION_UP){
//Move up
y -= speed;
}
else if (userInput.getyDirection() == DIRECTION_DOWN){
//Move down
y += speed;
}
else{
//Log.d("yMove", "yDirection unrecognised");
}
}
//Get x and y for Logic
public int getX() {
return x;
}
public int getY() {
return y;
}
public Bitmap getSprite() {
return sprite;
}
}
Logic.java
package com.Frenchie.SpaceshipSammy;
import ...
public class Logic implements Runnable {
//Bring in required classes
private Player player;
//Player variables
private int yPlayer, xPlayer;
private Bitmap playerSprite;
public Logic(Context context){
player = new Player(context);
//Sprite currently wont change so this doesn't need to be updated with the location
playerSprite = player.getSprite();
//Creating and running thread
Thread thread = new Thread(this);
thread.start();
}
//Thread to tell the players position update method to run and update the players values in this class
#Override
public void run() {
while(true) {
player.PositionUpdate();
PlayerLocation();
}
}
//Updates the players location which can be passed onto GameView
public void PlayerLocation(){
xPlayer = player.getX();
yPlayer = player.getY();
}
//Getters for GameView to use
public int getyPlayer() {
return yPlayer;
}
public int getxPlayer() {
return xPlayer;
}
public Bitmap getPlayerSprite() {
return playerSprite;
}
}
GameView.java
package com.Frenchie.SpaceshipSammy;
import ...
public class GameView extends SurfaceView implements Runnable{
private SurfaceHolder surfaceHolder = getHolder();
private Canvas canvas;
//Link Logic class
private Logic logic;
public GameView(Context context) {
super(context);
//Creates logic as a new object
logic = new Logic(context);
//Creates and starts the thread
Thread thread = new Thread(this);
thread.start();
}
//Override thread method. This is called when the thread is started
#Override
public void run() {
while (true){
DrawFrame();
}
}
private void DrawFrame(){
canvas = surfaceHolder.lockCanvas();
if (surfaceHolder.getSurface().isValid()){
canvas.drawColor(Color.MAGENTA);
canvas.drawBitmap(logic.getPlayerSprite(), logic.getxPlayer(), logic.getyPlayer(), null);
surfaceHolder.unlockCanvasAndPost(canvas);
} else {
Log.d("DrawFrame", "Surface Invalid");
}
}
}
All help is appreciated!
This is your problem, in your GameView
userInput = new Game();
You are pointing to a new instance of your Activity, not the actual Activity that is displayed. You need to set this value after the Player is created with the activity instance 'this'.

How to draw a graph of a mathematical function, on an Android canvas

How might I draw a graph of a function (for example, y = x^2 or y = (x +1)/(2*x +3)) on a Canvas in an Android app?
Here you have an example code ;D (plots the f(x)=x^3 function)
A sample thread that plots the function.
public class MainThread extends Thread {
private static final String TAG = MainThread.class.getSimpleName();
private SurfaceHolder surfaceHolder;
private MainGamePanel gamePanel;
private Paint paintRed;
private Paint paintBlue;
private boolean running;
public void setRunning(boolean running) {
this.running = running;
}
public MainThread(SurfaceHolder surfaceHolder, MainGamePanel gamePanel) {
super();
this.paintRed = new Paint();
this.paintRed.setColor(Color.RED);
this.paintRed.setStrokeWidth(1);
this.paintBlue = new Paint();
this.paintBlue.setColor(Color.BLUE);
this.paintBlue.setStrokeWidth(1);
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
}
class MeasuredAxis {
public static final int X_GAP = 1;
public static final int Y_GAP = 1;
int _realHeight;
int _realWidth;
public MeasuredAxis(int width, int height) {
_realWidth = width;
_realHeight = height;
}
public int getXAxisNegLimit() {
return (_realWidth / 2)*(-1);
}
public int getXAxisLimit() {
return (_realWidth / 2);
}
public float getXMeasured(int x) {
return ((_realWidth / 2) + x);
}
public float getYMeasured(float y) {
return ((_realHeight / 2) - y);
}
}
private float function(float x) {
return new Double(Math.pow(x, 3)).floatValue();
}
#Override
public void run() {
long fps = 0L;
Log.d(TAG, "Starting game loop");
Canvas canvas = surfaceHolder.lockCanvas();
MeasuredAxis measured = new MeasuredAxis(canvas.getWidth(), canvas.getHeight());
synchronized (canvas) {
int x = measured.getXAxisNegLimit();
//from -x to +x evaluate and plot the function
while (x++ < measured.getXAxisLimit()) {
canvas.drawLine(
measured.getXMeasured(x),
measured.getYMeasured(function(x)),
measured.getXMeasured(x+MeasuredAxis.X_GAP),
measured.getYMeasured(function(x+MeasuredAxis.Y_GAP)),
paintRed);
}
canvas.save();
canvas.translate(0, 0);
canvas.scale(canvas.getWidth(), canvas.getHeight());
canvas.restore();
}
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
A sample surface view where the function is drawn.
public class MainGamePanel extends SurfaceView implements
SurfaceHolder.Callback {
private MainThread thread;
public MainGamePanel(Context context) {
super(context);
getHolder().addCallback(this);
// create the game loop thread
thread = new MainThread(getHolder(), this);
setFocusable(true);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
thread.setRunning(true);
thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
// try again shutting down the thread
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
#Override
protected void onDraw(Canvas canvas) {
}
}
And an example activity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(new MainGamePanel(this));
}
}
Hope this helps you!

how to get objects of calling thread with implements runnable?

Hello I have a question with my code. As you can see below, I have r.getBlink() under OnDraw() method. Is there a function to determine if the "s" thread calls the OnDraw(). I mean I tried this.getClass().getBlink() but it displays as an error. help please.
public class main extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new BitmapView(this));
}
}
class BitmapView extends View implements OnTouchListener{
Circle r = new Circle();
Circle s = new Circle();
public BitmapView(Context context) {
super(context);
this.setOnTouchListener(this);
r.starter();
s.starter();
}
public void onDraw(Canvas canvas){
Paint paint = new Paint();
if (r.getBlink()==true){
paint.setColor(Color.YELLOW);
r.setBlink(false);
}
else{
paint.setColor(Color.BLACK);
r.setBlink(true);
}
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(r.getX(), r.getY(), 15, paint);
invalidate();
}
class Circle implements Runnable{
Random rnd=new Random();
int x=rnd.nextInt(200), y=rnd.nextInt(200);
boolean blink = false;
public int getX(){ return this.x; }
public int getY(){ return this.y; }
public boolean getBlink() { return this.blink; }
public void setBlink(boolean b) { this.blink=b; }
public void starter(){
Thread running=new Thread(this);
running.start();
x=rnd.nextInt(200);
y=rnd.nextInt(200);
}
public void run(){
while(true){
try {
Thread.sleep(rnd.nextInt(2000));
} catch (Exception ex) {ex.printStackTrace();}
}
}
}
Thread.currentThread().get Name();
-This method will give you the name of the currently executing thread object. I believe this is what you want.

Categories

Resources