We will set camera bound to set certain limits in camera movement, so for example camera will not follow player after following down and dying. Will stop on 0 coordinate on the X axis. First thing we need to do, is to change our camera type to
BoundCamera instead of Camera.
edit our activity class, change camera type to BoundCamera.
camera = new BoundCamera(0, 0, 800, 480);
edit BaseScene and ResourcesManager class, replacing Camera to BoundCamera type.
after correcting all errors reported by eclipse (simply changing camera type) open GameScene class, lets set camera bounds, based on data received from level data filed.
inside loadLevel method, you can see two commented lines (width and height) uncomment them, and lets set camera bounds using them:
levelLoader.registerEntityLoader(new EntityLoader<SimpleLevelEntityLoaderData>(LevelConstants.TAG_LEVEL)
{public IEntity onLoadEntity(finalString pEntityName,final IEntity pParent,final Attributes pAttributes,final SimpleLevelEntityLoaderData pSimpleLevelEntityLoaderData)throwsIOException{finalint width = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_LEVEL_ATTRIBUTE_WIDTH);finalint height = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_LEVEL_ATTRIBUTE_HEIGHT);
camera.setBounds(0,0, width, height);// here we set camera bounds
camera.setBoundsEnabled(true);return GameScene.this;}});
We set camera min. bounds to (0x,0y) and maximum to values parsed from level file (in our previously level file it will be (2000x,700y) because of this line:
<level width="1000" height="780">
2. コインを収集する:
コインを収集してスコアにポイントを追加し、収集した後にはコインを非表示する方法を説明します。
Go to the loadLevel code, to the line where we create coin, we left onManageUpdate method commented and left undone, now we will insert there code responsible for checking if player collides with coin. That`s how it should look like:
levelObject = new Sprite(x, y, resourcesManager.coin_region, vbom)
{@Override
protectedvoid onManagedUpdate(float pSecondsElapsed){super.onManagedUpdate(pSecondsElapsed);if(player.collidesWith(this)){
addToScore(10);this.setVisible(false);this.setIgnoreUpdate(true);}}};
Lets take care about possibility to collect coins, add points to the score, and set coins invisible after collecting them. Go to the loadLevel code, to the line where we create coin, we left onManageUpdate method commented and left undone, now we will insert there code responsible for checking if player collides with coin. That`s how it should look like:
levelObject = new Sprite(x, y, resourcesManager.coin_region, vbom)
{@Override
protectedvoid onManagedUpdate(float pSecondsElapsed){super.onManagedUpdate(pSecondsElapsed);if(player.collidesWith(this)){
addToScore(10);this.setVisible(false);this.setIgnoreUpdate(true);}}};
This code check on every update, if player collides with coin, and if does, we are adding 10 points to the score, using our previously created method, setting coin to invisible, and setting coin to ignore update (so it will not update any more, since its already collected)
go to loadLevel function, to the line where we initialize our player, inside onDie execute code responsible for displaying game over text, firstly checking if it was not displayed:
@Override
public void onDie()
{if(!gameOverDisplayed){
displayGameOverText();}}
3. Handling player die event:
Now lets implement player die event, every time player will fall down (player`s Y value less than 0) we will display "game over". Latter you can implement game restart function after clicking this message or something similar, depends on your needs, for now lets just display message every time player die (fall down).
create two new fields, text for game over message, and boolean for flag if this message has been displayed already (to prevent from displaying again)
private Text gameOverText;private boolean gameOverDisplayed = false;
create method initializing game over text and method displaying it:
Method displaying game over text, firstly disable camera chase entity, than set game over text to the current camera`s center position, attach message and set flag to true.
execute createGameOverText() method into createScene() method.
go to loadLevel function, to the line where we initialize our player, inside onDie execute code responsible for displaying game over text, firstly checking if it was not displayed:
@Override
public void onDie()
{if(!gameOverDisplayed){
displayGameOverText();}}
ここでは、コンタクトリスナーの全てのbeginContactとendContact 内で、まずはfixture Aとfixture Bがユーザーデータを取得できるかどうか確認します(これらfixtures A と B は、beginContactのような特定のイベント間で発生する fixtures です)。後半では x2 body のユーザーデータが "player"に等しいかどうかを確認し、等しい場合は(begin contactでは)foot contactの値を増加させ、 ( end contactでは)foot contactの値を減少させます。 Keep in mind that player could be also fixture A (x1) so it might be useful to also check if x1 body user data equals player (In practice, you can make an educated guess about which fixture is which, mainly based on the order that you created things in the world) In this case, for our code it should work just fine.
4. Disabling possibility to multi jump, contact listener:
Currently, please is able to jump infinity times without firstly touching ground, we will fix it now, by using simple trick combined with contact listener.
open Player class, create new int field to store contact`s count:
private int footContacts = 0;
create methods to increase (++) and decrease (--) this value
public void increaseFootContacts()
{
footContacts++;}public void decreaseFootContacts()
{
footContacts--;}
modify jump function to check if this value is higher than 0. If it is, we will let player to jump. We will increase this value every time player will touch platform, and decrease every time he will end contact with platform.
public void jump()
{if(footContacts <1){return;}
body.setLinearVelocity(new Vector2(body.getLinearVelocity().x,12));}
open GameScene class, lets create contact listener. What is it? It lets us to execute code while events such as contact begin/end between fixtures occurs. We can recognise fixtures/bodies by setting their user data as we did for example for players body by settings its user data to "player".
Here it is, our contact listener, on every beginContact and endContact we firstly check if fixture A and fixture B got user data (those fixtures A and B are fixtures between certain event such as begin contact occurs) Latter we check if the x2 body user data equals "player" and if yes we increase (on begin contact) our foot contact value or decrease it (on end contact) Keep in mind that player could be also fixture A (x1) so it might be useful to also check if x1 body user data equals player (In practice, you can make an educated guess about which fixture is which, mainly based on the order that you created things in the world) In this case, for our code it should work just fine.
register contact listener for our physics world, inside method responsible for creating our physics world, like this:
Done, we just fixed our "infinity jump" issue, now it should be fine, latter we will use contact listener to add functions for our platforms (such as falling platforms after contact with player and so on) That`s all for this article.