Search code examples
javaandroidbitmapspritegame-physics

Background moves farther and faster than anything else


OK, So Im drawing a bitmap beneath everything else for my background. Whenever the player moves it moves the enemy array 1 px and its supposed to do the same for the background. But whenever I move the background goes way faster and farther than everything else in the game. Can anyone tell me whats causing this? Heres the code. The code that moves everything is at the bottom in the set direction method.

package com.gametest;

import java.util.concurrent.CopyOnWriteArrayList;
import android.app.Activity;
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.graphics.Rect;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;

public class GameSurfaceView extends Activity implements OnTouchListener {

    double ran;
    int touchX, touchY, screenWidth, screenHeight, objX, objY;
    static int bgx, bgy, bgW, bgH, enemyCount, score, playerHealth;
    static boolean canUpdate;
    static MyView v;
    static Bitmap orb, orb2, explosion, bg;
    static CopyOnWriteArrayList<Sprite> copy = new CopyOnWriteArrayList<Sprite>();
    static String hpString;
    static Player player;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        v = new MyView(this);
        v.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent me) {
                switch (me.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    return true;
                case MotionEvent.ACTION_MOVE:
                    return true;
                case MotionEvent.ACTION_UP:
                    touchX = (int) me.getX();
                    touchY = (int) me.getY();
                    for (Sprite sprite : copy) {
                        sprite.checkTouch(touchX, touchY);
                        return true;
                    }
                }
            return true;
            }
        });

        canUpdate = true;
        screenWidth = v.getWidth();
        screenHeight = v.getHeight();
        playerHealth = 250;
        hpString = "Health " + playerHealth;
        ran = 0;
        score = 0;
        orb = BitmapFactory.decodeResource(getResources(), R.drawable.blue_orb);
        orb2 = BitmapFactory.decodeResource(getResources(), R.drawable.red_orb);
        bg = BitmapFactory.decodeResource(getResources(), R.drawable.bg1);
        bgx = bg.getHeight()/2;
        bgy = bg.getHeight()/2;
        bgH = bg.getHeight();
        bgW = bg.getWidth();
        explosion = BitmapFactory.decodeResource(getResources(), R.drawable.explosion);
        player = new Player(v, orb2, explosion, screenWidth, screenHeight);
        createEnemies();
        setContentView(v);

    }

    private void createEnemies() {
        if (enemyCount < 5) {
            screenWidth = v.getWidth();
            screenHeight = v.getHeight();
            copy.add(new Sprite(v, orb, explosion, screenWidth, screenHeight, copy.size()));
            enemyCount++;
        }
    }

    public static void checkECount(int id) {
        canUpdate = false;
        copy.remove(id);
        enemyCount--;
        CopyOnWriteArrayList<Sprite> c = new CopyOnWriteArrayList<Sprite>();
        int index = 0;
        for (Sprite s : copy) {
            s.ID = index;
            c.add(s);
            index++;
        }
        score = score + 10;
        copy = c;
        canUpdate = true;
    }

    @Override
    protected void onPause() {
        super.onPause();
        v.pause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        v.resume();
    }

    public class MyView extends SurfaceView implements Runnable {

        Thread t = null;
        SurfaceHolder holder;
        boolean isItOk = false;

        public MyView(Context context) {
            super(context);
            holder = getHolder();

        }

        @Override
        public void run() {
            while (isItOk == true) {
                if (!holder.getSurface().isValid()) {
                    continue;
                }
                Canvas c = holder.lockCanvas();
                if (canUpdate) {
                    canvas_draw(c);
                }
                holder.unlockCanvasAndPost(c);
                try {
                    t.sleep(50);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }

        }

        protected void canvas_draw(Canvas canvas) {
            canvas.drawColor(Color.BLACK);
            Rect bgRec = new Rect(bgx, bgy, bgx+bgW, bgy+bgH);
            canvas.drawBitmap(bg, null, bgRec, null);
            ran = Math.random() * 5;
            if (ran > 4.5) {
                createEnemies();
            }
            Paint paint = new Paint();
            paint.setColor(Color.BLACK);
            paint.setTextSize(15);
            canvas.drawText(hpString, 10, 25, paint);
            for (Sprite sprite : copy) {
                sprite.sprite_draw(canvas);
            }
            Player.sprite_draw(canvas, copy);

        }

        public void pause() {
            isItOk = false;
            while (true) {
                try {
                    t.join();
                } catch (InterruptedException e) {

                }
                break;
            }
            t = null;
        }

        public void resume() {
            isItOk = true;
            t = new Thread(this);
            t.start();
        }

    }

    @Override
    public boolean onTouch(View arg0, MotionEvent arg1) {
        return false;
    }

    public static void damagePlayer() {
        hpString = "Health " + playerHealth;
        playerHealth = playerHealth - 5;
        if (playerHealth < 0) {
            hpString = "game over";
        }
    }

    public static void setDirection(int i, int j) {
        if (i == 0 && j == -1) {
            for (Sprite s : copy) {
                s.y++;
                bgy++;
            }
        }
        if (i == 0 && j == 1) {
            for (Sprite s : copy) {
                s.y--;
                bgy--;
            }
        }
        if (i == -1 && j == 0) {
            for (Sprite s : copy) {
                s.x++;
                bgx++;
            }
        }
        if (i == 1 && j == 0) {
            for (Sprite s : copy) {
                s.x--;
                bgx--;
            }
        }

    }

}

Solution

  • You are changing bgx based on the number of sprites you have in your copy Iterable. in your setDirection method, please move the bgy, bgx outside of the enhanced for loops, like in:

    if (i == 0 && j == -1) {
        for (Sprite s : copy) {
            s.y++;
        }
        bgy++;
    }