Reputation: 11
I'm fairly new to Android and I am having trouble loading images. My current code looks like this:
package com.android.skeleton;
import java.io.IOException;
import java.io.InputStream;
import java.util.Random;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.media.SoundPool;
public class GameModel extends Game {
private Bitmap background;
private Bitmap gameover;
public final int PLAYER = 0;
public final int ENEMY = 1;
public final int EXIT = 2;
public final int BIGENEMY = 3;
private int health;
Sprite player;
Enemy enemy1;
Enemy enemy2;
BigEnemy enemy3;
Enemy enemy4;
Enemy enemy5;
Enemy enemy6;
Exit exit;
//Images
Bitmap cat;
Bitmap jellyfish;
Bitmap bigdog;
Bitmap exitTile;
SoundPool music;
SoundPool damageSound;
Context context;
InputStream inputStream = null;
private static GameModel gameModel = null;
public static GameModel getGameModel(){
if(gameModel == null){
gameModel = new GameModel();
}
return gameModel;
}
private GameModel(){
}
public void update(){
}
public void draw(Canvas canvas){
}
public boolean processTouchEvent(int x, int y){
return false;
}
@Override
public void gameStart() {
// TODO Auto-generated method stub
try{
AssetManager assetManager = context.getAssets();
inputStream = assetManager.open("/resources/blackcat.png");
cat = BitmapFactory.decodeStream(inputStream);
inputStream.close();
inputStream = assetManager.open("/resources/Jellyfish1.png");
jellyfish = BitmapFactory.decodeStream(inputStream);
inputStream.close();
inputStream = assetManager.open("/resources/Dog.png");
bigdog = BitmapFactory.decodeStream(inputStream);
inputStream.close();
inputStream = assetManager.open("/resources/exit.png");
exitTile = BitmapFactory.decodeStream(inputStream);
inputStream.close();
inputStream = assetManager.open("/resources/kitchen.png");
background = BitmapFactory.decodeStream(inputStream);
inputStream.close();
inputStream = assetManager.open("/resources/endscreen.png");
gameover = BitmapFactory.decodeStream(inputStream);
inputStream.close();
}catch(IOException ex){}
gameSetBackground(background);
player = new Sprite(cat, 0);
enemy1 = new Enemy(jellyfish, 0);
enemy2 = new Enemy(jellyfish, 0);
enemy4 = new Enemy(jellyfish, 0);
enemy5 = new Enemy(jellyfish, 0);
enemy6 = new Enemy(jellyfish, 0);
enemy3 = new BigEnemy(bigdog, 1.4);
exit = new Exit (exitTile, 0);
player.setLocation(320, 480);
player.setType(0);
player.setActive();
health = 10;
enemy1.setLocation(0, 160);
enemy1.setVelocity(5, 0);
enemy1.setType(1);
enemy1.setActive();
enemy2.setLocation(640, 320);
enemy2.setVelocity(-5, 0);
enemy2.setType(1);
enemy2.setActive();
Random random = new Random();
Random random2 = new Random();
int i = Math.abs(random.nextInt() % 10);
int j = Math.abs(random2.nextInt() % 10);
while (i < 2){
i = Math.abs(random.nextInt() % 10);
}
while (j < 2){
j = Math.abs(random.nextInt() % 10);
}
enemy4.setLocation(640, 0);
enemy4.setVelocity(-i, j);
enemy4.setType(1);
enemy4.setActive();
Random random3 = new Random();
Random random4 = new Random();
int k = Math.abs(random3.nextInt() % 10);
int l = Math.abs(random4.nextInt() % 10);
while (k < 2){
k = Math.abs(random.nextInt() % 10);
}
while (l < 2){
l = Math.abs(random.nextInt() % 10);
}
enemy5.setLocation(0, 480);
enemy5.setVelocity(k, l);
enemy5.setType(1);
enemy5.setActive();
enemy6.setLocation(600, 440);
enemy6.setVelocity(0, -5);
enemy6.setType(1);
enemy6.setActive();
exit.setLocation(600, 0);
exit.setVelocity(0, 0);
exit.setType(2);
exit.setActive();
//Add sprites to game
gameAddSprite(player);
gameAddSprite(enemy1);
gameAddSprite(enemy2);
gameAddSprite(enemy3);
gameAddSprite(enemy4);
gameAddSprite(enemy5);
gameAddSprite(enemy6);
gameAddSprite(exit);
}
@Override
public void gameEnd() {
// TODO Auto-generated method stub
player.setInactive();
enemy1.setInactive();
enemy2.setInactive();
enemy3.setInactive();
enemy4.setInactive();
enemy5.setInactive();
enemy6.setInactive();
exit.setInactive();
gameSetBackground(gameover);
}
@Override
public void gameUpdate(Canvas canvas) {
// TODO Auto-generated method stub
player.update();
enemy1.rotate(0.1);
enemy1.update();
enemy2.rotate(0.1);
enemy2.update();
enemy3.update();
enemy4.rotate(0.1);
enemy4.update();
enemy5.rotate(0.1);
enemy5.update();
enemy6.rotate(0.2);
enemy6.update();
if(enemy3.getPosy() == 430){
enemy3.setInactive();
}
if(health == 0){
gameEnd();
}
}
@Override
public void spriteCollide(Sprite s1, Sprite s2) {
// TODO Auto-generated method stub
if(s2.getType() == ENEMY && s1.getType() == PLAYER)
{
health -= 1;
}
if(s2.getType() == BIGENEMY && s1.getType() == PLAYER)
{
health -= 1;
}
if (s2.getType() == EXIT && s1.getType() == PLAYER)
{
gameEnd();
}
if(s2.getType() == ENEMY && s1.getType() == ENEMY)
{
double i = s2.getVelx();
double j = s2.getVely();
double k = s1.getVelx();
double l = s1.getVely();
s2.setVelocity(-i, -j);
s1.setVelocity(-k,-l);
}
}
public void actionPerformed() {
// TODO Auto-generated method stub
//Create random spawn positions for bigdogs
Random random = new Random();
Random random2 = new Random();
int xPos = Math.abs(random.nextInt() % 640);
int yVel = Math.abs(random2.nextInt() % 20);
//Make sure y velocity is between 10 and 30. Set this way for now
//to hide problems with individual enemy3 sprites becoming inactive.
while (yVel < 10)
yVel = Math.abs(random.nextInt() % 30);
//Spawn big dogs with random x position and y velocity
//according to timer settings.
enemy3.setLocation(xPos, 0);
enemy3.setActive();
enemy3.setVelocity(0, -yVel);
enemy3.setType(3);
}
@Override
public void gameCheckInputs() {
// TODO Auto-generated method stub
}
}
I'm aware I'm probably doing something stupid and it will probably be a very quick fix.
UPDATED WITH FULL CODE
Here's the log file:
04-30 03:49:19.490: W/dalvikvm(749): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
04-30 03:49:19.560: E/AndroidRuntime(749): FATAL EXCEPTION: main
04-30 03:49:19.560: E/AndroidRuntime(749): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.skeleton/com.android.skeleton.Android_SkeletonActivity}: java.lang.NullPointerException
04-30 03:49:19.560: E/AndroidRuntime(749): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
04-30 03:49:19.560: E/AndroidRuntime(749): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
04-30 03:49:19.560: E/AndroidRuntime(749): at android.app.ActivityThread.access$600(ActivityThread.java:123)
04-30 03:49:19.560: E/AndroidRuntime(749): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
04-30 03:49:19.560: E/AndroidRuntime(749): at android.os.Handler.dispatchMessage(Handler.java:99)
04-30 03:49:19.560: E/AndroidRuntime(749): at android.os.Looper.loop(Looper.java:137)
04-30 03:49:19.560: E/AndroidRuntime(749): at android.app.ActivityThread.main(ActivityThread.java:4424)
04-30 03:49:19.560: E/AndroidRuntime(749): at java.lang.reflect.Method.invokeNative(Native Method)
04-30 03:49:19.560: E/AndroidRuntime(749): at java.lang.reflect.Method.invoke(Method.java:511)
04-30 03:49:19.560: E/AndroidRuntime(749): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
04-30 03:49:19.560: E/AndroidRuntime(749): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
04-30 03:49:19.560: E/AndroidRuntime(749): at dalvik.system.NativeStart.main(Native Method)
04-30 03:49:19.560: E/AndroidRuntime(749): Caused by: java.lang.NullPointerException
04-30 03:49:19.560: E/AndroidRuntime(749): at com.android.skeleton.Game.gameSetBackground(Game.java:61)
04-30 03:49:19.560: E/AndroidRuntime(749): at com.android.skeleton.GameModel.gameStart(GameModel.java:98)
04-30 03:49:19.560: E/AndroidRuntime(749): at com.android.skeleton.GameSurfaceView.<init>(GameSurfaceView.java:23)
04-30 03:49:19.560: E/AndroidRuntime(749): at com.android.skeleton.Android_SkeletonActivity.onCreate(Android_SkeletonActivity.java:18)
04-30 03:49:19.560: E/AndroidRuntime(749): at android.app.Activity.performCreate(Activity.java:4465)
04-30 03:49:19.560: E/AndroidRuntime(749): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
04-30 03:49:19.560: E/AndroidRuntime(749): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
Here's the gameSetBackground
public void gameSetBackground(Bitmap i){
backgroundImage = i;
if (clearList == null){
clearList = new LinkedList<Rect>(); }
clearList.add(new Rect(0, 0, canvas.getWidth(), canvas.getHeight()));
}
Here's Game.java
package com.android.skeleton;
import java.util.LinkedList;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.Log;
import android.view.SurfaceHolder;
public abstract class Game implements Runnable {
private LinkedList<Sprite> spriteList;
public LinkedList<Sprite> sprites(){
return spriteList;
}
private LinkedList<Rect>clearList;
private Thread gameThread;
private Bitmap backgroundImage=null;
Canvas canvas;
SurfaceHolder surfaceHolder = null;
Canvas backGraphics;
public abstract void gameStart();
public abstract void gameEnd();
public abstract void gameUpdate(Canvas c);
public abstract void spriteCollide(Sprite s1, Sprite s2);
public void init(){
spriteList = new LinkedList<Sprite>();
clearList = new LinkedList<Rect>();
canvas = new Canvas();
}
public void setDebugOn(){
for(Sprite s: spriteList)
s.showRectangle();
}
public void setDebugOff(){
for(Sprite s: spriteList)
s.hideRectangle();
}
public void gameAddSprite(Sprite s){
spriteList.add(s);
}
public void gameAddSprites(Sprite []slist){
for(Sprite sp: slist)
spriteList.add(sp);
}
public void gameSetBackground(Bitmap i){
backgroundImage = i;
if (clearList == null){
clearList = new LinkedList<Rect>(); }
clearList.add(new Rect(0, 0, canvas.getWidth(), canvas.getHeight()));
}
public void start(){
gameThread = new Thread(this);
gameThread.start();
gameStart();
}
public void stop(){
gameEnd();
gameThread = null;
}
public void update(Canvas canvas){
for(Sprite s: spriteList){
if(s.needsCleared()){
}
gameUpdate(backGraphics);
paint(canvas);}
}
public void paint(Canvas canvas){
if(backgroundImage != null) {
for(Rect r: clearList){
backGraphics.drawBitmap(backgroundImage,
r.left, r.top, null);
}
} else {
for(@SuppressWarnings("unused") Rect r: clearList){
}
}
clearList.clear();
int n = spriteList.size();
for(int i=n-1; i>=0; i--){
spriteList.get(i).draw(backGraphics);
}
}
public void run() {
while(gameThread == Thread.currentThread()){
if(surfaceHolder.getSurface().isValid()){
canvas = new Canvas();
canvas = surfaceHolder.lockCanvas();
gameCheckInputs();
checkCollisions();
paint(canvas);
try{
Thread.sleep(40);
}
catch(InterruptedException ex){
ex.printStackTrace();
}
}
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
private void checkCollisions(){
if(spriteList.size() > 1){
int nsprites = spriteList.size();
for(int i=0; i<nsprites; i++) if(spriteList.get(i).isActive()){
for(int j = i+1; j<nsprites; j++) if(spriteList.get(j).isActive()){
if(spriteList.get(i).getRect().intersect(spriteList.get(j).getRect())){
spriteCollide(spriteList.get(i), spriteList.get(j));
}
}
}
}
}
public void gameCheckInputs() {
// TODO Auto-generated method stub
}
public void gameStart(Context context) {
// TODO Auto-generated method stub
}
}
Upvotes: 0
Views: 809
Reputation: 31283
I'm having a difficult time following your code, but one problem I see, at least to fix your exception, is that you are calling getWidth()
on the canvas probably before the canvas has been drawn to. In the onCreate()
method of an activity, your activity has not been drawn to the screen yet, so this is not a good time to manipulate the canvas of a View
. The best advice I can give to know for sure is to extend SurfaceView
and override the onDraw()
method, then use your custom SurfaceView
in your XML layout with the fully quantified name, such as <com.android.skeleton.MySurfaceView />
.
For example:
public class MySurfaceView extends SurfaceView {
public MySurfaceView(Context context) {
this(context, null, 0);
}
public MySurfaceView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MySurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Draw some stuff
}
}
If you're inflating your layout in XML, you would use your custom view like this:
<com.mypackage.MySurfaceView
...
/>
Upvotes: 0
Reputation: 11
Basically what I was doing wrong was I wasn't calling the Init inside my Game.java class, I put in a few catches, e.g.
if (clearList == null){
clearList = new LinkedList<Rect>(); }
I now have the problem that it's displaying nothing but a blank screen but it'd probably be a better idea if I were to make a new question for this problem, thank you all for your help however!
Upvotes: 0
Reputation: 79
Hi nutriletter, May i know what u really trying to do in -
public void gameSetBackground(Bitmap i){
backgroundImage = i;
if (clearList == null){
clearList = new LinkedList<Rect>(); }
clearList.add(new Rect(0, 0, canvas.getWidth(), canvas.getHeight()));
}
You're not using the backgroundImage
Am i right or not?
try this -
if(backgroundImage!=null)
rest of ur code..
Upvotes: 1
Reputation: 32222
Put your images into assets folder instead of putting it into assets/resources folder and use the below code to retrieve the images.
try {
InputStream bitmap=getAssets().open("icon.png");
Bitmap bit=BitmapFactory.decodeStream(bitmap);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Upvotes: 0