In my game the kid is collecting fruits but if he hits the rock 3 times or time is up before collecting the required points, the kid will jump to the half of the screen then fall down and start fail music then move to game over screen but I have two problems here:
when time is up the boy jump to top and continue out of the screen not the bottom and the music of fail is slow and choppy.
when kid hits rock 3 times it start fail music well and jump to the center of screen and fall down out of the screen from bottom and this is very good then go to game over screen, but when i go back from game over screen,the music of the Play screen is not working:
here is the code :
public boolean Rockhit()
{
if(Rocks.isRock) {
rocknum--;
Hud.collectorLives(rocknum);
Rocks.isRock=false;
if (rocknum == 0)
return true;
else
return false;
}
else
Hud.collectorLives(rocknum);
return false;
}
public State getState()
{
//Gdx.app.log(Float.toString(b2body.getLinearVelocity().x),"hi");
if ((Hud.getTime()==0&& Hud.getScore()<(level*30)+50)) {
Fruits.manager.get("music/Backmusic.ogg", Music.class).stop();
collectoIsDead=true;
Filter filter = new Filter();
filter.maskBits = Fruits.NOTHING_BIT;
for (Fixture fixture : b2body.getFixtureList())
fixture.setFilterData(filter);
b2body.applyLinearImpulse(new Vector2(0, 5f), b2body.getWorldCenter(), true);
//b2body.applyLinearImpulse(new Vector2(0,-2.5f), b2body.getWorldCenter(), true);
Fruits.manager.get("music/fail.mp3", Sound.class).play();
return State.DEAD;
}
if ( Rockhit()) {
Fruits.manager.get("music/Backmusic.ogg", Music.class).stop();
collectoIsDead=true;
Filter filter = new Filter();
filter.maskBits = Fruits.NOTHING_BIT;
for (Fixture fixture : b2body.getFixtureList())
fixture.setFilterData(filter);
b2body.applyLinearImpulse(new Vector2(0, 5f), b2body.getWorldCenter(), true);
//b2body.applyLinearImpulse(new Vector2(0,-2.5f), b2body.getWorldCenter(), true);
Fruits.manager.get("music/fail.mp3", Sound.class).play();
return State.DEAD;
}
if((Hud.getTime()==0&& Hud.getScore()>=(level*30)+50)|| (Hud.getScore()>=(level*30)+50)) {
Fruits.manager.get("music/Backmusic.ogg", Music.class).stop();
Fruits.manager.get("music/cheering.mp3", Sound.class).play();
return State.SUCCESS;
}
this is the code of gameover screen:
public class GameOverScreen implements Screen {
private Viewport viewport;
private Stage stage;
private Fruits game;
private float level;
public GameOverScreen(Fruits game,float level)
{
this.level=level;
this.game=game;
viewport=new FitViewport(Fruits.V_WIDTH,Fruits.V_HIEGT,new OrthographicCamera());
stage=new Stage(viewport,((Fruits) game).batch);
Label.LabelStyle font = new Label.LabelStyle(new BitmapFont(), Color.WHITE);
Table table=new Table();
table.center();
table.setFillParent(true);//the table will take all the stage
Label gameOverLabel = new Label("Game Over",font);
Label playAgainLabel = new Label("Click Here",font);
table.add(gameOverLabel).expandX();
table.row();
table.add(playAgainLabel).expandX().padTop(10f);// make it bellow Game over text by 10 pixels
stage.addActor(table);
}
#Override
public void render(float delta) {
if(Gdx.input.isTouched()) {
game.setScreen(new Worlds(game,level));
dispose();
}
Gdx.gl.glClearColor(0,0,0,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.draw();
}
#Override
public void show() {
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
}
here where I am processing the state of the kid in the play screen:
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
kid.draw(batch);
if(gameOver())//24
{
gameisover=true;
globalcounter--;
Gdx.app.log(Float.toString(globalcounter), "counter");
if(globalcounter==0) {
game.setScreen(new GameOverScreen(game, level));
dispose();
}
}
if(gameisover==true) {
globalcounter--;
Gdx.app.log(Float.toString(globalcounter), "counter");
if (globalcounter == 0) {
game.setScreen(new GameOverScreen(game, level));
dispose();
}
}
if(nextLevel())
{
prefs = Gdx.app.getPreferences("levels");
String name=prefs.getString("level", " ");
if(name==" ") {
prefs.putString("level", Float.toString(level + 1));
prefs.flush();
}
else {
prefs.putString("level", Float.toString(level+1));
prefs.flush();
}
game.setScreen(new Celebration(game,level+1));
dispose();
}
}
public boolean gameOver()//25
{
if(player.currentState== Collector.State.DEAD )// will show the game over screen after 3 seconds
{
return true;
}
return false;
}
public boolean nextLevel()//25
{
if(player.currentState== Collector.State.SUCCESS)// will show the game over screen after 3 seconds
{
return true;
}
return false;
}
Well, to start off with, your structure is flawed.
Your getState does not just return a state. A lot of things are happening before you return a state. You should really move those things and do them AFTER you have changed state.
I don't see a State.PLAYING? You only have 2 states DEAD and SUCCESS
You stop your background music:
Fruits.manager.get("music/Backmusic.ogg", Music.class).stop();
But it looks like you never start it again.
Related
Im trying to make snake game and im using my implementation of ScheduledService to move rectangles to imitate movement.
Problem is that ScheduledService seems to have trouble with adding new nodes. To check if im correct i tried adding huge rectangle on a runtime and whole window doesnt refresh (when i remove line about this rectangle snake still moves but food cannot be seen). How do i make sure that task adds node to my scene?
I tried my methods without concurrency and everything works fine.
public class GameLoop extends ScheduledService {
GameScene scene;
Square first;
Direction direction;
GameLoop(GameScene scene){
this.scene=scene;
setPeriod(new Duration(150));
}
#Override
protected Task createTask() {
return new Task<Void>() {
#Override
protected Void call() throws Exception {
if(!gameOver()){
if (scene.getSnake().move(direction, scene.getFood())) {
scene.placeFood();
return null;
}
}else{
System.out.println("game over");
cancel(false);
}
return null;
}
};
}
public void setDirection(Direction direction){
this.direction=direction;
}
}
public class GameScene extends Scene {
private Snake snake;
private Square food;
private Pane pane;
int i=0;
//======================================================================
GameScene(double x, double y, Pane pane){
super(pane, x, y);
this.pane=pane;
pane.setBackground(new Background(new BackgroundFill(Color.BLACK, null, null)));
snake=new Snake(x, y);
placeFood();
pane.getChildren().add(snake);
}
//=====================================================================
public void placeFood(){
//If i add this the whole window freezes
/*
if(i>0) {
pane.getChildren().add(new Rectangle(100, 100, Color.BLUE));
}
*/
food=new Square(10, 10, Color.RED);
System.out.println(food.hashCode());
System.out.println("Setting new Food");
do {
food.setX(DataViability.roundTen(Math.random() *this.getWidth() - 10));
food.setY(DataViability.roundTen(Math.random()*this.getHeight() - 10));
}while(snake.onSnake(food, true));
System.out.println("Broke out");
pane.getChildren().add(food);
// This sout doesnt appear on the console when adding food in a GameLoop
System.out.println("Set food at : " + food.getX() + " " + food.getY());
i++;
}
So i want to make a menu for a simple java game where the buttons changes colors when the mouse hovers over them. I am not using JButton but a picture of a button that uses mouselistener to detect the click. How do i make it so MouseEntered is called when you hover over a specific area where the button is?
public void mouseEntered(MouseEvent e) {
if(e.getX() < 950 && e.getX() > 350 && e.getY() < 300 && e.getY() > 200){
menuImage2 = true;
menuImage1 = false;
}
}
This is what i have so far
This is how I did it. It also plays a sound too. You just use flags. Notice, I used mouseMoved rather than mouseEntered.
Class MouseInput
#Override
public void mouseMoved(MouseEvent e) {
int x=e.getX();
int y=e.getY();
if (x>100&&x<200&&y>150&&y<200) {
if (mouseInStart==false) { <---- if this line is true, means mouse entered for first time.
Sound.playSound(soundEnum.BUTTONHOVER);
}
mouseInStart=true;
} else {
mouseInStart=false;
}
}
public boolean mouseInStart() { <--use this in your update method
return mouseInStart;
}
And in my other class (Class Menu)
public void render(Graphics2D g) {
....
....
gradient = new GradientPaint(100, 150, setStartColor(), 200, 200, Color.gray);
g.setPaint(gradient);
g.fill(startButton);
}
public Color setStartColor() {
if (mouseInStart) {
return Color.red;
} else {
return Color.white;
}
}
public void update() { <--- and this is to keep checking if your mouse is in start. This is part of the giant game loop.
mouseInStart=mouseInput.mouseInStart();
mouseInLoad=mouseInput.mouseInLoad();
mouseInQuit=mouseInput.mouseInQuit();
}
I'm writing a "space invaders" style app and I needed to do the move stop repeat animation that is classic to the game. I got the processes to go one way, using the code below, however when I want to go back, there does not seem to be an easy way to do this. I think the easiest way to do it is to have something happen on the end animation event, however I cannot get the event to trigger, even when calling super.end();. I've looked around for a way to trigger the event manually but to no avail. The way I am doing this may be a little sketchy but it works well enough right now to try and make it work all the way.
public void start()
{
if(begin < end) //recursive end condition
{
int distance = interval + begin; //change the distance to be traveled
//create new animation to do part of the whole animation
ObjectAnimator anim = ObjectAnimator.ofFloat(toAnimate, property, begin,distance);
TimeInterpolator inter = new TimeInterpolator() //makes the animation move with only one frame
{
public float getInterpolation(float prog)
{
return Math.round(prog * 10) / 10;
}
};
anim.setInterpolator(inter);
anim.setDuration((long)(500));
anim.addListener(new AnimatorListener()
{
#Override
public void onAnimationStart(Animator animation){}
#Override
public void onAnimationEnd(Animator animation)
{
start(); //start the next part of the movement
}
#Override
public void onAnimationCancel(Animator animation){}
#Override
public void onAnimationRepeat(Animator animation){}
});
begin = begin + interval; //update end recursion value
anim.start(); //begin the animation
}
super.end(); //this doesn't work... rip
}
public void start()
{
if(begin < end) //recursive end condition
{
int distance = interval + begin; //change the distance to be traveled
//create new animation to do part of the whole animation
ObjectAnimator anim = ObjectAnimator.ofFloat(toAnimate, property, begin,distance);
TimeInterpolator inter = new TimeInterpolator() //makes the animation move with only one frame
{
public float getInterpolation(float prog)
{
return Math.round(prog * 10) / 10;
}
};
anim.setInterpolator(inter);
anim.setDuration((long)(500));
anim.addListener(new AnimatorListener()
{
#Override
public void onAnimationStart(Animator animation){}
#Override
public void onAnimationEnd(Animator animation)
{
begin += interval;
if(begin < end){
start(); //start the next part of the movement
}
else{
// Do something else
}
}
#Override
public void onAnimationCancel(Animator animation){}
#Override
public void onAnimationRepeat(Animator animation){}
});
anim.start(); //begin the animation
}
}
I'm using AndEngine and Box2d in android application.
What do I have to do so that when pushing the "leftArrow" and "rightArrow" buttons, the player doesn't start moving too fast because of the too frequent call of the "Update Handler" method? I want the player to move constantly with the same speed.
//same for leftArrow
Sprite rightArrow = new Sprite(...) {
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
float pTouchAreaLocalX, float pTouchAreaLocalY) {
if(pSceneTouchEvent.isActionDown()) {
goRight = true;
}
else if(pSceneTouchEvent.isActionUp()) {
goRight = false;
}
return true;
}
};
private IUpdateHandler UpdateHandler = new IUpdateHandler(){
#Override
public void onUpdate(float pSecondsElapsed) {
if(goLeft) {
playerBody.applyForce(-50, 0, body.getWorldCenter().x, body.getWorldCenter().y);
}
if(goRight){
playerBody.applyForce(50, 0, body.getWorldCenter().x, body.getWorldCenter().y);
}
}
};
use setLinearVelocity instead of applyForce. It should work
For the game I'm currently writing for Android devices, I've got a class called RenderView, which is a Thread and updates and renders everything. Occasionally the class logs the message "Game thread is only updating the update method and is not rendering anything". The game is running at 30 fps on my nexus s. And I get the message a couple of times throughout the session. Could someone tell me how I could optimize the class or if I'm forgetting something or that it's totally normal?
Here's my code:
public class RenderView extends SurfaceView implements Runnable {
public final String classTAG = this.getClass().getSimpleName();
Game game;
Bitmap framebuffer;
Thread gameloop;
SurfaceHolder holder;
boolean running;
int sleepTime;
int numberOfFramesSkipped;
long beginTime;
long endTime;
long lastTime;
int differenceTime;
int framePeriod;
Canvas canvas;
int frameCount;
WSLog gameEngineLog;
public RenderView(Game game, Bitmap framebuffer) {
super(game);
this.game = game;
this.framebuffer = framebuffer;
this.holder = getHolder();
framePeriod = 1000/game.getFramesPerSecond();
lastTime = System.currentTimeMillis();
gameEngineLog = game.getGameEngineLog();
}
#Override
public void run() {
while(running == true) {
if(holder.getSurface().isValid()) {
beginTime = System.currentTimeMillis();
numberOfFramesSkipped = 0;
game.getCurrentScreen().update();
game.getCurrentScreen().render(); // Draw out everything to the current virtual screen (the bitmap)
game.getGraphics().renderFrameBuffer(); // Actually draw everything to the real screen (combine both bitmaps)
canvas = holder.lockCanvas();
if(canvas != null) { // Fix for mysterious bug ( FATAL EXCEPTION: Thread)
// The viewing area of our virtual screen on our real screen
canvas.drawBitmap(framebuffer, null, game.getWSScreen().getGameScreenextendeddst(), null);
holder.unlockCanvasAndPost(canvas);
}
else {
gameEngineLog.e(classTAG, "Surface has not been created or otherwise cannot be edited");
}
endTime = System.currentTimeMillis();;
differenceTime = (int) (endTime - beginTime);
sleepTime = (int) (framePeriod - differenceTime);
if(sleepTime > 0) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
else {
while(sleepTime < 0 && numberOfFramesSkipped < game.getMaxFrameSkippes()) {
gameEngineLog.d(classTAG, "Game thread is only updating the update method and is not rendering anything");
try {
Thread.sleep(5);
}
catch (InterruptedException exception) {
exception.printStackTrace();
}
game.getCurrentScreen().update();
sleepTime += framePeriod;
numberOfFramesSkipped++;
}
}
// Frame Per Second Count
frameCount++;
if(lastTime + 1000 < System.currentTimeMillis()) {
game.getGameEngineLog().d(classTAG, "REAL FPS: " + frameCount);
lastTime = System.currentTimeMillis();
frameCount = 0;
}
}
}
}
public void resume() {
running = true;
gameloop = new Thread(this);
gameloop.start();
}
public void pause() {
running = false;
while(running == true) {
try {
gameloop.join();
running = false;
}
catch (InterruptedException e) {
}
}
gameloop = null;
}
}
Here's the code for the Graphics class (the getGraphics() just return an graphics object):
public class Graphics {
public final String classTAG = this.getClass().getSimpleName();
Game game;
Canvas frameBuffer;
Canvas canvasGameScreenextended;
Canvas canvasGameScreen; // Used for customeScreen
Bitmap gameScreenextended;
Bitmap gameScreen;
Rect gameScreendst;
Rect gameScreenextendeddst;
WSLog gameEngineLog;
Graphics(Game game, Bitmap framebuffer, Bitmap gameScreen) {
this.game = game;
// Initialize canvases to render to
frameBuffer = new Canvas(framebuffer);
canvasGameScreen = new Canvas(gameScreen);
// Initialize images to be rendered to our composition
this.gameScreen = gameScreen;
// Set up the Log
gameEngineLog = game.getGameEngineLog();
}
public void resetCanvasGameScreenextended() {
// This method has to be called each time the screen scaling type changes
canvasGameScreenextended = new Canvas(game.getWSScreen().getGameScreenextended());
gameScreenextended = game.getWSScreen().getGameScreenextended();
}
public Canvas getCanvasGameScreenextended() {
return canvasGameScreenextended;
}
public Canvas getCanvasGameScreen() {
return canvasGameScreen;
}
public void renderFrameBuffer() {
// Composition
// First layer (bottom)
frameBuffer.drawBitmap(gameScreen, null, game.getWSScreen().getGameScreendst(), null);
// Second layer (top)
frameBuffer.drawBitmap(gameScreenextended, null, game.getWSScreen().getGameScreenextendeddst(), null);
}
public void clearFrameBuffer() {
canvasGameScreen.drawColor(Color.BLACK);
//canvasGameScreenextended.drawColor(Color.BLACK);
gameScreenextended.eraseColor(Color.TRANSPARENT); // Make top layer transparent
}
}
Here's the code for the screen class (the getCurrentScreen() method returns a screen object):
public class Screen {
public final String classTAG = this.getClass().getSimpleName();
protected final Game game;
protected final Graphics graphics;
protected Screen(Game game) {
this.game = game;
this.graphics = game.getGraphics();
//game.getInput().reset();
}
public void update() {
}
public void render() {
}
/** Initialize all the sensory that should be used within this screen.*/
public void resume() {
}
public void pause() {
game.getInput().useAccelerometer(false);
game.getInput().useKeyboard(false);
game.getInput().useTouchscreen(false);
}
public void onDispose() {
game.getGraphics().clearFrameBuffer();
}
public void setScreenResizeType(int screenResizeType) {
}
The Screen class is extended and the render() method is shadowed with methods like:
graphics.getCanvasGameScreen().drawRect(play, red);
The funny thing is, when I override the render() method and don't place any code in it, the logger fires constantly with the message: "Game thread is only updating the update method and is not rendering anything". What kind of sorcery is this?!
Help is hugely appreciated!
As far as I understand from your updated post, there is no rendering problem actually. Instead, your code mistakenly prints that message.
This is because you check if(sleepTime > 0) , so if the rendering is very fast and sleepTime is zero, you get that message. Just change it to if(sleepTime >= 0).