Jump to content
  • Advertisement
Schoppi99

Java Problem with simple Game in Android Studio

Recommended Posts

Hi,

I have a problem with my programm and i cant find any solution...

I wrote a simple 2D game. The background is moving and accelerating slowly. On the right side there is the player, he is fixed and not movable. Now I want carrots moving with the same speed as the background towards the player.

So i used the exact same speed like the background, but i set them as an Array List. Now the carrots spawn, they start with the same speed like the background, but then they get slower and slower instead of faster and faster.

If i dont declare them as an ArrayList it works, but i want multiple carrots on the screen.

Would be really nice if someone has an idea,

Thank You!!!

Share this post


Link to post
Share on other sites
Advertisement
15 minutes ago, Schoppi99 said:

Hi,

I have a problem with my programm and i cant find any solution...

I wrote a simple 2D game. The background is moving and accelerating slowly. On the right side there is the player, he is fixed and not movable. Now I want carrots moving with the same speed as the background towards the player.

So i used the exact same speed like the background, but i set them as an Array List. Now the carrots spawn, they start with the same speed like the background, but then they get slower and slower instead of faster and faster.

If i dont declare them as an ArrayList it works, but i want multiple carrots on the screen.

Would be really nice if someone has an idea,

Thank You!!!

It's extremely hard for anyone to help you if you're not going to provide the actual code relevant to your problem.

Beyond that, did you run a debugger to see what is causing the variable to make the speed slow down? My guess is that you're not loading the arraylist with new objects, but without code to review it could be anything.

Share this post


Link to post
Share on other sites

Yes sorry, here is the code of the Carrot:

package com.example.philippschopp.hasinimmersatt;

import android.graphics.Bitmap;
import android.graphics.Canvas;

public class GoodFood extends GameObject{
    private Bitmap image;
    private float funktion, dx = GamePanel.MOVESPEED;
    private Speed speed;
    public GoodFood(Bitmap res,int x, int y){
        speed = new Speed();
        width=369;
        height=796;
        super.x = x;
        super.y = y;
        image=res;
    }
    public void update(){
        speed.update();
        x= (float) (x+speed.getSpeed());
    }

    public void draw(Canvas canvas){
        try{
            canvas.drawBitmap(image,x,y,null);
        } catch (Exception e){}
    }
}

like the background it gets the speed by speed.getSpeed() of this class:

package com.example.philippschopp.hasinimmersatt;

public class Speed {
    public double dx=GamePanel.MOVESPEED,funktion;
    public double getSpeed(){
        return funktion;
    }
    public void update(){
        dx+=0.05;
        funktion=(-0.1*dx);
    }
}

And this is the GamePanel, in the update method i add new goodfood=carrots or badfood, but i think badfood is not relevant here, because its the same problem with both, and they are almost exactly the same:

package com.example.philippschopp.hasinimmersatt;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.provider.Settings;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.util.ArrayList;
import java.util.Random;


public class GamePanel extends SurfaceView implements SurfaceHolder.Callback {


    public static final int WITDH = 3072;
    public static final int HEIGHT = 1536;
    public static final int MOVESPEED = 100;
    private ArrayList<GoodFood> goodfood;
    private ArrayList<BadFood> badfood;
    private Player player;
    private MainThread thread;
    private BackgroundFront bgf;
    private Speed speed;
    public int iforfood = 1;
    public Random rand = new Random();
    public int carrotcount=0;

    public GamePanel(Context context) {
        super(context);

        //add the callback to the surfaceHolder to intercept events
        getHolder().addCallback(this);

        thread = new MainThread(getHolder(), this);

        //make gamePanel focusable so that it can handle events
        setFocusable(true);
    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        bgf = new BackgroundFront(BitmapFactory.decodeResource(getResources(), R.drawable.background));
        player = new Player(BitmapFactory.decodeResource(getResources(), R.drawable.hasi), 400, 467, 8);
        goodfood = new ArrayList<>();
        badfood = new ArrayList<>();
        speed = new Speed();
        //safely start the game loop
        thread.setRunning(true);
        thread.start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        boolean retry = true;
        int counter = 0;
        while (retry && (counter < 1000)) {
            counter++;
            try {
                thread.setRunning(false);
                thread.join();
                retry = false;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (!player.getPlaying()) {
                player.setPlaying(true);
            }
            return true;
        }
        return super.onTouchEvent(event);
    }

    public void update() {

        if (player.getPlaying()) {
            bgf.update();
            player.update();
            speed.update();
            //food
            if (bgf.getVerschoben() == iforfood) {
                int gob = rand.nextInt(2);
                if(gob==0) {
                    goodfood.add(new GoodFood(BitmapFactory.decodeResource(getResources(), R.drawable.carrot),WITDH+10,HEIGHT-(204+796-30)));
                    iforfood++;
                }
                else if(gob==1){
                    badfood.add(new BadFood(BitmapFactory.decodeResource(getResources(), R.drawable.poison_bottle)));
                    iforfood++;
                }
            }

            for(int i=0; i<goodfood.size();i++){
                goodfood.get(i).update();

                if(collision(goodfood.get(i), player)){
                    kollision=true;
                    goodfood.remove(i);
                    carrotcount++;
                    player.setScore(carrotcount);
                    break;
                }

                if(goodfood.get(i).getX()<-WITDH-500){
                    goodfood.remove(i);
                    break;
                }

            }



            for(int i=0; i<badfood.size();i++){
                badfood.get(i).update();
            }

        }
    }

    public boolean collision(GameObject a, GameObject b){
        if(Rect.intersects(a.getRect(),b.getRect())) {
            return true;
        }
        return false;
    }
public boolean kollision;
    @SuppressLint("MissingSuperCall")
    @Override
    public void draw(Canvas canvas) {
        final float scaleFactorX = getWidth() / (float) WITDH;
        final float scaleFactorY = getHeight() / (float) HEIGHT;
        if (canvas != null) {
            final int savedState = canvas.save();
            canvas.scale(scaleFactorX, scaleFactorY);
            bgf.draw(canvas);
            player.draw(canvas);
            for (GoodFood g : goodfood) {
                g.draw((canvas));
            }
            // for (BadFood b : badfood) {
            //      b.draw((canvas));
            //}
            canvas.drawText(Integer.toString(player.getScore()), WITDH/2, HEIGHT-300, null);
            canvas.restoreToCount(savedState);
        }

    }

}

maybe you also want to see the background class:

package com.example.philippschopp.hasinimmersatt;

import android.graphics.Bitmap;
import android.graphics.Canvas;

public class BackgroundFront {

    private Bitmap image;
    private Speed speed;
    private float xfront,yfront,xverschiebung,funktionfront, verschoben=0, dx = GamePanel.MOVESPEED;

    public BackgroundFront(Bitmap res){
        image=res;
        speed = new Speed();
    }
    public void update(){
        speed.update();
        xfront= (float) (xfront+speed.getSpeed());
        xverschiebung= (float) (xverschiebung+speed.getSpeed());

        if(xverschiebung<-500){
            verschoben++;
            xverschiebung=0;
        }
        if(xfront<-GamePanel.WITDH){
            xfront=0;
        }
    }


    public void draw(Canvas canvasfront){
       canvasfront.drawBitmap(image,xfront,yfront,null);
       if(xfront<0){
           canvasfront.drawBitmap(image,xfront+GamePanel.WITDH,yfront,null);
       }
    }
    public float getVerschoben() {return verschoben;}

}

And yes i runned a debuger, but i could not figure it out.. because i add the same speed to the background and the carrot...

Thank you for your answer!

Edited by Schoppi99

Share this post


Link to post
Share on other sites

Thank you. :)

I’ve reviewed your project and I believe I have a solution for your issue. My understanding is that your background moves gradually faster as speed will increase per tick as you continue to update speed, and when new food spawns (good or bad food) the speed rate doesn’t sync with the background making them ‘slower’.

The reason for this is because when you first TAP the screen and your background starts to update, but when you’re spawning your objects you’re not taking the current speed of the background to sync the objects to. You're setting a new speed on spawn and starting the calculation once update hits.

Here is an example:

If your background is moving at (x) speed and you want your objects to match the same speed, then when you update the object just pass in the current background speed value in. You’re running into this issue because you’re starting a new speed tracker on object creation. You’ll know this is true because if you run the game you’ll see the objects begin overlapping after awhile as the background grows faster and faster.

To fix this you will need to do the following:

In BackgroundFront.java you’ll have to make a getter for the speed:

public double getSpeed() {

        return speed.getSpeed();

    }

In GamePanel.java you need to do the following:

Change:

goodfood.get(i).update();

To:

goodfood.get(i).update(bgf.getSpeed());

 

Then in GoodFood.java change:

public void update(){

        speed.update();

        x= (float) (x+speed.getSpeed());

    }

To:

public void update(double speedFromBgf){

        x= (float) (x+speedFromBgf);

    }

You’ll have to do the same for BadFood and any other objects which spawn.

This should fix your problem! :) Let me know!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!