Draw method not working - java

So i've started learnin android studio game development from this series: https://www.youtube.com/watch?v=Rliwg0sELJo and i can't seem to find the reason why my draw method isn't working. i triple checked my code and the video and ran some tests to try and find my error but ended up blank.
please keep in mind i'm new to stackoverflow and programming so if you see any ways i can improve on stuff like formatting i'd love to hear it
MainActivity:
import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new GamePanel(this));
}
}
GamePanel:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback {
private MainThread thread;
private RectPlayer player;
private Point playerPoint;
public GamePanel(Context context){
super(context);
getHolder().addCallback(this);
thread=new MainThread(getHolder(),this);
player = new RectPlayer(new Rect(100,100,200,200), Color.rgb(255,0,0));
playerPoint=new Point(150,150);
setFocusable(true);
}
#Override
public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){
}
#Override
public void surfaceCreated(SurfaceHolder holder){
thread = new MainThread(getHolder(),this);
thread.setRunning(true);
thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
while(retry){
try{
thread.setRunning(false);
thread.join();
}catch(Exception e){e.printStackTrace();}
retry=false;
}
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
playerPoint.set((int)event.getX(),(int)event.getY());
}
return true;
//return super.onTouchEvent(event);
}
public void update(){
player.update(playerPoint);
System.out.println(playerPoint.x);
System.out.println(playerPoint.y);
}
#Override
public void draw(Canvas canvas){
super.draw(canvas);
canvas.drawColor(Color.BLUE);
player.draw(canvas);
}
}
MainThread:
package com.example.student.game_core1;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
public class MainThread extends Thread {
public static final int MAX_FPS=30;
private double averageFPS;
private SurfaceHolder surfaceHolder;
private GamePanel gamePanel;
private boolean running;
public static Canvas canvas;
public void setRunning(boolean running){
this.running=running;
}
public MainThread(SurfaceHolder surfaceHolder,GamePanel gamePanel){
super();
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
}
#Override
public void run(){
long startTime;
long timeMillis;
long waitTime;
int frameCount=0;
long totalTime=0;
long targetTime=1000/MAX_FPS;
while (running){
startTime=System.nanoTime();
canvas=null;
try{
canvas=this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder){
this.gamePanel.update();
this.gamePanel.draw(canvas);
}
}catch(Exception e){
e.printStackTrace();
}finally {
if(canvas!=null){
try{
surfaceHolder.unlockCanvasAndPost(canvas);
}catch(Exception e){e.printStackTrace();}
}
}
timeMillis=(System.nanoTime()-startTime)/1000000;
waitTime=targetTime - timeMillis;
try{
if(waitTime>0)
this.sleep(waitTime);
}catch(Exception e) {e.printStackTrace();}
totalTime+=System.nanoTime()-startTime;
frameCount++;
if(frameCount==MAX_FPS){
averageFPS=1000/(totalTime/frameCount/1000000);
frameCount=0;
totalTime=0;
System.out.println(averageFPS);
}
}
}
}
RectPlayer:
package com.example.student.game_core1;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
public class RectPlayer implements GameObject {
private Rect rectangle;
private int color;
public RectPlayer(Rect rectangle, int color){
this.rectangle=rectangle;
this.color=color;
}
#Override
public void draw(Canvas canvas){
Paint paint=new Paint();
paint.setColor(color);
canvas.drawRect(rectangle,paint);
}
#Override
public void update(){
}
public void update(Point point){
rectangle.set((point.x)-(rectangle.width()/2),(point.y)-(rectangle.height()/2),(point.x)+(rectangle.width()/2),(point.y)+(rectangle.height()/2));
}
public Rect getRectangle() {
return rectangle;
}
}

If im not wrong you are using Canvas, trying to draw your item with draw() method.
It seems that you need to use another method (onDraw(Canvas)):
Draw your graphics in a Canvas object. To use this option, you pass your canvas to the appropriate class' onDraw(Canvas) method. You can also use the drawing methods in Canvas. This option also puts you in control of any animation.
If you need more info about canvas, just go here --> https://developer.android.com/guide/topics/graphics/2d-graphics.html

Related

Cant draw rectangle on canvas [Android Studio Game]

so i was following retro-chickens tutorial online on how to make a 2d game on android studio and i have run across a problem and i tried to figure it out but i just cant seemm to find a solution. The problem occured on his 2nd video (https://www.youtube.com/watch?v=Rliwg0sELJo) where he runs his code and rectangle appears on the screen which he can move around. For me the rectangle doesnt appear on the canvas for some reason, it is just a blank canvas even though i have the exact same code as him (i have gone back and checked).
At times my application sometimes doesnt even launch and gives me error like this (I have the latest sdk version and everything):
Cold swapped changes.
$ adb shell am start -n "com.example.ridhavraj.stardrifter/com.example.ridhavraj.stardrifter.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Connected to process 3319 on device emulator-5554
W/System: ClassLoader referenced unknown path: /data/app/com.example.ridhavraj.stardrifter-2/lib/x86
I/InstantRun: Instant Run Runtime started. Android package is com.example.ridhavraj.stardrifter, real application class is null.
W/System: ClassLoader referenced unknown path: /data/app/com.example.ridhavraj.stardrifter-2/lib/x86
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 1
[ 11-11 20:20:52.858 3319: 3343 D/ ]
HostConnection::get() New Host Connection established 0xaee13300, tid 3343
A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 3343 (Thread-5)
[ 11-11 20:20:53.138 1214: 1214 W/ ]
debuggerd: handling request: pid=3319 uid=10072 gid=10072 tid=3343
Application terminated.
Here is the code that i have made from the video:
[GameObject Interface]
package com.example.ridhavraj.stardrifter;
import android.graphics.Canvas;
public interface GameObject {
public void draw(Canvas canvas);
public void update();
}
[MainActivity Class]
package com.example.ridhavraj.stardrifter;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
//setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new GamePanel(this));
}
}
[MainThread Class]
package com.example.ridhavraj.stardrifter;
import android.graphics.Canvas;
import android.provider.Settings;
import android.view.SurfaceHolder;
public class MainThread extends Thread{
public static final int MAX_FPS = 30;
private double averageFPS;
private SurfaceHolder surfaceHolder;
private GamePanel gamePanel;
private boolean running;
public static Canvas canvas;
public void setRunning(boolean running)
{
this.running = running;
}
public MainThread(SurfaceHolder surfaceHolder, GamePanel gamePanel)
{
super();
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
}
#Override
public void run()
{
long startTime;
long timeMillis = 1000/MAX_FPS;
long waitTime;
int frameCount = 0;
long totalTime = 0;
long targetTime = 1000/MAX_FPS;
while(running)
{
startTime = System.nanoTime();
canvas = null;
try
{
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder)
{
this.gamePanel.update();
this.gamePanel.draw(canvas);
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (canvas != null)
{
try
{
surfaceHolder.unlockCanvasAndPost(canvas);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
timeMillis = (System.nanoTime()-startTime)/1000000;
waitTime = targetTime - timeMillis;
try
{
if (waitTime > 0)
{
this.sleep(waitTime);
}
}
catch (Exception e)
{
e.printStackTrace();
}
totalTime += System.nanoTime() - startTime;
frameCount++;
if (frameCount == MAX_FPS)
{
averageFPS = 1000/((totalTime/frameCount)/1000000);
frameCount = 0;
totalTime = 0;
System.out.println(averageFPS);
}
}
}
}
[GamePanel Class]
package com.example.ridhavraj.stardrifter;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback {
private MainThread thread;
private Player player;
private Point playerPoint;
public GamePanel(Context context)
{
super(context);
getHolder().addCallback(this);
thread = new MainThread(getHolder(), this);
player = new Player(new Rect(100,100,200,200), Color.rgb(255,0,0));
playerPoint = new Point(150,150);
setFocusable(true);
}
#Override
public void surfaceChanged(SurfaceHolder Holder, int format, int width, int height)
{
}
#Override
public void surfaceCreated(SurfaceHolder holder)
{
thread = new MainThread(getHolder(), this);
thread.setRunning(true);
thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
boolean retry = true;
while(true)
{
try
{
thread.setRunning(false);
thread.join();
}
catch (Exception e)
{
e.printStackTrace();
}
retry = false;
}
}
public boolean onTouchEvent(MotionEvent event)
{
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
playerPoint.set((int)event.getX(), (int)event.getY());
}
return true;
//return super.onTouchEvent(event);
}
public void update()
{
player.update(playerPoint);
}
#Override
public void draw(Canvas canvas)
{
super.draw(canvas);
canvas.drawColor(Color.WHITE);
player.draw(canvas);
}
}
[Player Class]
package com.example.ridhavraj.stardrifter;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Canvas;
import android.graphics.Rect;
public class Player implements GameObject{
private Rect rectangle;
private int color;
public Player(Rect rectangle, int Color)
{
this.rectangle = rectangle;
this.color = color;
}
#Override
public void draw(Canvas canvas)
{
Paint paint = new Paint();
paint.setColor(color);
canvas.drawRect(rectangle, paint);
}
#Override
public void update()
{
}
public void update(Point point)
{
//l,t,r,b
rectangle.set(point.x-rectangle.width()/2, point.y-rectangle.height()/2, point.x+rectangle.width()/2, point.y+rectangle.height()/2);
}
}
I dont clue what i am doing wrong, any help would be greatly appreciated.
Well Turns out guys, i am retarded, there was a typo in the player class
private Rect rectangle;
private int color;
public Player(Rect rectangle, int Color [THIS SHOULD BE 'color' and not 'Color')
{
this.rectangle = rectangle;
this.color = color;
}
for 3D Rectangle(cube) copy whole code to your CustomView Class
Paste This into onDraw() method
drawCube(
fp.mX.toInt(), fp.mY.toInt(),
100 + (fp.mCx.toInt() - fp.mX.toInt()),
100 + fp.mCy.toInt() - fp.mY.toInt(),
mPaint, mCanvas!!
)
drawCube(
fp.mX.toInt(), fp.mY.toInt(),
100 + (fp.mCx.toInt() - fp.mX.toInt()),
100 + fp.mCy.toInt() - fp.mY.toInt(),
mStrokePaint, mCanvas!!
)
3D Cube Function Code
private fun drawCube(
x: Int,
y: Int,
width: Int,
height: Int,
paint: Paint,
canvas: Canvas
) {
val p1 = Point(x, y)
val p2 = Point(x, y + height)
val p3 = Point(x + width, y + height)
val p4 = Point(x + width, y)
val p5 = Point(x + width / 2, y - height / 2)
val p6 = Point(x + 3 * width / 2, y - height / 2)
val p7 = Point(x + 3 * width / 2, y + height / 2)
val path = Path()
path.fillType = Path.FillType.EVEN_ODD
path.moveTo(p1.x.toFloat(), p1.y.toFloat())
path.lineTo(p2.x.toFloat(), p2.y.toFloat())
path.lineTo(p3.x.toFloat(), p3.y.toFloat())
path.lineTo(p4.x.toFloat(), p4.y.toFloat())
path.lineTo(p1.x.toFloat(), p1.y.toFloat())
path.lineTo(p5.x.toFloat(), p5.y.toFloat())
path.lineTo(p6.x.toFloat(), p6.y.toFloat())
path.lineTo(p4.x.toFloat(), p4.y.toFloat())
path.moveTo(p3.x.toFloat(), p3.y.toFloat())
path.lineTo(p7.x.toFloat(), p7.y.toFloat())
path.lineTo(p6.x.toFloat(), p6.y.toFloat())
path.lineTo(p4.x.toFloat(), p4.y.toFloat())
path.close()
canvas.drawPath(path, paint)
}

moving sprites in Android

I am making a game which requires the sprites to move towards the bottom of the screen. You can imagine it a bit like a rhythm game(guitar hero). However, I am having problems as the sprites are not moving at all even if the loop seems to work fine.
The GamePanel-
package com.jollygent.tapthepointer;
import java.util.ArrayList;
import java.util.Random;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class GamePanel extends SurfaceView{
SurfaceHolder holder;
GameLoopThread loop;
GamePanel game = this;
Random rand;
int y;
//ArrayList<Pointers> pointers = new ArrayList<Pointers>();
Pointers pointers;
public GamePanel(Context context) {
super(context);
holder = getHolder();
loop = new GameLoopThread(this);
rand = new Random();
pointers = new Pointers(rand.nextInt(4)+1,getWidth()/2,0,this);
//placeholder
this.setBackgroundColor(Color.WHITE);
holder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
loop.setRunning(false);
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
loop = new GameLoopThread(game);
if(!loop.isRunning()){
loop.setRunning(true);
loop.start();
}
else{
loop.setPause(false);
}
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stubn
}
});
}
public GameLoopThread getLoop(){
return loop;
}
public void update(){
}
public void draw(Canvas canvas){
pointers.draw(canvas);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStrokeWidth(20);
paint.setStyle(Paint.Style.STROKE);
canvas.drawLine(0,getHeight()/2 + 50,getWidth(),getHeight()/2 + 50, paint);
}
}
The Pointer class
package com.jollygent.tapthepointer;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
public class Pointers {
GamePanel game;
private int x,y;
Bitmap pointer;
Bitmap rotated_pointer;
Matrix matrix;
public Pointers(int type,int x,int y,GamePanel game){
this.game = game;
this.x = x;
this.y = y;
pointer = BitmapFactory.decodeResource(game.getResources(),R.drawable.pointer_xx);
matrix = new Matrix();
switch(type){
//points right
case 1:
matrix.postRotate(90);
break;
//points left
case 2:
matrix.postRotate(-90);
break;
//points up
case 3:
rotated_pointer = pointer;
break;
//points down
case 4:
matrix.postRotate(180);
break;
}
rotated_pointer = Bitmap.createBitmap(pointer,0,0,pointer.getHeight(),pointer.getWidth(), matrix,true);
}
public void update(){
/*if(y < game.getHeight()){
y += pointer.getHeight();
}*/
}
public int getHeight(){
return pointer.getHeight();
}
public void draw(Canvas canvas){
y++;//placeholder movement to see if the sprite actually moves. It doesn't.
canvas.drawBitmap(rotated_pointer,x,y,null);
}
}
Finally, I think it's necessary to post the GameLoopThread-
package com.jollygent.tapthepointer;
import android.graphics.Canvas;
public class GameLoopThread extends Thread{
GamePanel game;
boolean running = false;
boolean paused = false;
Canvas canvas;
static final int FPS = 10;
public GameLoopThread(GamePanel game){
this.game = game;
}
public boolean isRunning(){
return running;
}
public void setRunning(boolean b){
this.running = b;
}
public void setPause(boolean b){
this.paused = b;
}
#Override
public void run() {
// TODO Auto-generated method stub
long beginTime;
long ticks = 1000/FPS;
long sleepTime;
while(running){
if(!paused){
beginTime = System.currentTimeMillis();
canvas = null;
try{
canvas = game.holder.lockCanvas();
synchronized(game.getHolder()){
game.draw(canvas);
}
}finally{
if(canvas != null){
game.getHolder().unlockCanvasAndPost(canvas);
}
}
sleepTime = (System.currentTimeMillis() - beginTime)/ticks;
try{
if(sleepTime > 0)
Thread.sleep(sleepTime);
else
Thread.sleep(10);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
}
I'm probably making a very stupid mistake, but no matter how much I scan into the code and change around few bits I can't seem to figure out how exactly to move the sprite. Also, how can I make it so the sprite is centered exactly in any device?
Thank you.
EDIT:
package com.jollygent.tapthepointer;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
public class GameActivity extends Activity {
GamePanel game;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
game = new GamePanel(this);
setContentView(game);
}
#Override
public void onPause(){
super.onPause();
game.getLoop().setPaused(true);
}
#Override
public void onResume(){
super.onResume();
game.getLoop().setPaused(false);
}
}
The problem is that the loop only runs once and once only. Perhaps the GameActivity is the problem?

Libgdx Desktop Launcher blank

Just starting Libgdx and java game development. Got a little bit of code to try and write a sprite sheet moving animation person, just started it so not finished by when i try an run it the single sprite drawing is not running, nothing is the desktop appliction is just black.
Desktop Launcher:
package com.mkgame.game1.desktop;
import com.MKgames.OptionScreen;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.mkgame.game1.Game1;
public class DesktopLauncher extends Game1{
public static void main (String[] arg) {
LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
cfg.title = "Game1";
cfg.width = 960;
cfg.height = 540;
new LwjglApplication(new Game1 (), cfg);
}
}
Main java class 'Game1':
package com.mkgame.game1;
import com.MKgames.FarmerAsset;
import com.MKgames.OptionScreen;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class Game1 extends ApplicationAdapter {
public OptionScreen game_screen;
public void create() {
FarmerAsset.load();
}
}
Game screen:
package com.MKgames;
import sun.java2d.loops.DrawGlyphListAA.General;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class OptionScreen implements Screen{
GameMain game;
OrthographicCamera camera;
SpriteBatch batch;
int farmerX;
public OptionScreen(GameMain game){
this.game = game;
camera = new OrthographicCamera();
camera.setToOrtho(true, 1920, 1080);
batch = new SpriteBatch();
farmerX = 960-85;
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0.95F, 0.95F, 0.95F, 0.95F);
camera.update();
generalUpdate();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(FarmerAsset.farmer1, farmerX, 200);
batch.end();
}
public void generalUpdate() {
if(Gdx.input.isKeyPressed(Keys.A)||Gdx.input.isKeyPressed(Keys.LEFT)){
farmerX -= 5;
}
else if(Gdx.input.isKeyPressed(Keys.D)||Gdx.input.isKeyPressed(Keys.RIGHT)){
farmerX += 5;
}
}
#Override
public void show() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
}
#Override
public void resize(int width, int height) {
}
#Override
public void hide() {
}
}
Change
public class Game1 extends ApplicationAdapter {
to
public class Game1 extends Game {
Create an instance of OptionScreen in Game:
public OptionScreen game_screen;
public void create() {
FarmerAsset.load();
game_screen = new OptionScreen(this);
setScreen(game_screen);
}
And it should be good to go.

Android nothing being drawn when onDraw is called?

Ok, so I've been working on a little game, and there's a problem in the rendering code. So, I tried to follow a tutorial for working with the SurfaceView, and so this is what I have so far:
GameSurface.java
package com.spng453.afirelitroom;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class GameSurface extends SurfaceView implements SurfaceHolder.Callback {
private GameThread thread;
public SurfaceHolder surfaceHolder;
DisplayMetrics metrics = GameActivity.metrics;
final private int sX = metrics.widthPixels;
final private int sY = metrics.heightPixels;
private Paint mainBTheme = new Paint();
Rect fireButton = new Rect(0, sY/2+50, sX, sY/2-50);
public GameSurface(Context context) {
super(context);
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
this.setWillNotDraw(false);
thread = new GameThread(surfaceHolder, this);
this.setFocusable(true);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
thread.setRunning(true);
thread.run();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean done = false;
while(!done) {
try {
thread.join();
done = true;
}
catch (InterruptedException e) {
}
}
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawRGB(255, 255, 0);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
return true;
}
}
and the code in
GameThread.java:
package com.spng453.afirelitroom;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceHolder;
public class GameThread extends Thread {
DisplayMetrics metrics = GameActivity.metrics;
final private int sX = metrics.widthPixels;
final private int sY = metrics.heightPixels;
private int FPS = 30;
private boolean running;
public SurfaceHolder surfaceHolder;
public GameSurface gameSurface;
public Canvas canvas;
private long firstTime = 0L, secondTime = 0L; //fps stuff
private Paint mainBTheme = new Paint();
//fire page
Rect fireButton = new Rect(0, sY/2+50, sX, sY/2-50);
Rect leftButton = new Rect();
Rect rightButton = new Rect();
//city/resources page
public void setRunning(boolean running) {
this.running = running;
}
public GameThread(SurfaceHolder surfaceHolder, GameSurface gameSurface) {
super();
this.surfaceHolder = surfaceHolder;
this.gameSurface = gameSurface;
mainBTheme.setColor(Color.BLACK);
}
#Override
public void run() {
while (running) {
//hey i guess i have to cap fps :(
firstTime = System.nanoTime();
//do the game here
canvas = null;
canvas = surfaceHolder.lockCanvas();
gameSurface.onDraw(canvas);
surfaceHolder.unlockCanvasAndPost(canvas);
secondTime = System.nanoTime();
if (secondTime/1000000 - firstTime/1000000 < 1000/FPS) { //the if the lag is less than the distance between frames at 30 fps
try {
Thread.sleep(1000/FPS - (secondTime/1000000 - firstTime/1000000));
} catch (InterruptedException e) {
}
}
}
}
}
So, my problem is that when I try to call onDraw in the GameThread here:
canvas = null;
canvas = surfaceHolder.lockCanvas();
gameSurface.onDraw(canvas);
surfaceHolder.unlockCanvasAndPost(canvas);
it does absolutely nothing. It doesn't draw whatever I put in onDraw, though if I put a Log call in the onDraw I know it executes. It doesn't produce an error message, either. Thanks for help in advanced!
Try this:
Change your method:
#Override
protected void onDraw(Canvas canvas) {
canvas.drawRGB(255, 255, 0);
}
By this:
#Override
protected void onDraw(Canvas canvas) {
canvas.drawRGB(255, 255, 0);
super.onDraw(canvas);
}
Also, try change this lines:
//do the game here
canvas = null;
canvas = surfaceHolder.lockCanvas();
gameSurface.onDraw(canvas);
surfaceHolder.unlockCanvasAndPost(canvas);
By this ones:
Canvas canvas = null;
try {
canvas = surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
gameSurface.onDraw(canvas);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (canvas != null)
surfaceHolder.unlockCanvasAndPost(canvas);
}
Also keep note that the while loop it's running really fast no giving chance to draw the canvas. The thread sleep isn't working very well. Look at this resources, there is explained how do the game loop properly. And if you wanna test it right now, just erase the while.
Android game loop explained
Android game basic structure
Hope this helps :]
Okay, so it turns out that it was a problem with the FPS code executing too fast. I solved it by doing this:
#Override
public void run() {
// TODO Auto-generated method stub
final int fps = 30;
Timer fpsTimer = new Timer();
fpsTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Canvas canvas;
canvas = null;
try {
canvas = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
onDraw(canvas);
}
} finally {
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}, 0, 1000/fps);
}

Canvas not drawing Android

I have been trying to start a new project and when I went to start up I couldn't get anything working. I have looked at the code for the past few hours and played with it but I can't remember how I fixed this last time it happened.
package org.waldev.canvascollisiontest;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class CollisionTest extends Activity {
private Panel game;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
game = new Panel(this);
setContentView(game);
}
public class Panel extends SurfaceView implements SurfaceHolder.Callback{
Threads thread;
public Panel(Context context) {
super(context);
thread = new Threads(this.getHolder(), this);
setFocusable(true);
}
public void onDraw(Canvas c)
{
c.drawColor(Color.BLUE);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
//when the game starts, run the thread\
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
holder.setFormat(PixelFormat.RGB_565);
thread.setRunning(true);
thread.start();
}
//if its destroyed, then destroy the thread
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
boolean retry = true;
thread.setRunning(false);
while (retry) {
try {
thread.join();
// bitmaps.recycleAll();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
}
}
And the thread:
package org.waldev.canvascollisiontest;
import org.waldev.canvascollisiontest.CollisionTest.Panel;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
public class Threads extends Thread{
SurfaceHolder surfaceHolder;
private Panel game;
private Canvas c;
private boolean isRunning = true;
// desired fps
private final static int MAX_FPS = 24;
// maximum number of frames to be skipped
private final static int MAX_FRAME_SKIPS = 0;
// the frame period
private final static int FRAME_PERIOD = 1000 / MAX_FPS;
public Threads(SurfaceHolder surfaceHolder, Panel panel){
this.surfaceHolder = surfaceHolder;
game = panel;
}
public void setRunning(boolean run){
isRunning = run;
}
public boolean getRunning(){
return isRunning();
}
public SurfaceHolder getSurface(){
return surfaceHolder;
}
#Override
public void run() {
Canvas canvas;
long beginTime; // the time when the cycle begun
long timeDiff; // the time it took for the cycle to execute
int sleepTime; // ms to sleep (<0 if we're behind)
int framesSkipped; // number of frames being skipped
boolean updated = false;
sleepTime = 0;
while (isRunning) {
canvas = null;
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
beginTime = System.currentTimeMillis();
framesSkipped = 0;
if(canvas != null)
{
game.onDraw(canvas);
}
timeDiff = System.currentTimeMillis() - beginTime;
sleepTime = (int)(FRAME_PERIOD - timeDiff);
if (sleepTime > 0) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {}
}
else
{
updated = false;
}
}
} finally {
// in case of an exception the surface is not left in
// an inconsistent state
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
} // end finally
}
}
public boolean isRunning() {
return isRunning;
}
}
I threw some break points in there and it is never calling surfaceCreated in CollisionTest. I know it has to be something stupid that I am missing here, so if you see it let me know. Thanks!
William
I got it working, I forgot to add the:
getHolder().addCallback(this);
to the Constructor for Panel, which is what was causing it to not work. Thanks!

Categories

Resources