Does anyone know Why The layer does not follow the player?
void HelloWorld::update (float delta) {
cocos2d::Size winSize = cocos2d::Director::getInstance()->getWinSize();
this->_player->setPosition(this->_player->getPosition().x , this->_player->getPosition().y + (10 * delta));
this->_background->setPosition(this->_player->getPosition().x , this->_player->getPosition().y);
this->setPosition(this->_player->getPosition().x + (winSize.width / 2),
this->_player->getPosition().y + (winSize.height / 3)); // Follow The player
}
The layer will not follow the player with the code you are using. Cocos2d-x provides you with a Follow action that you can attach to a node, and run on the layer you want to make follow the player. See below for example code.
auto followAction = Follow::create(playerNode, Rect());
// The Rect you give is the bounds the player can move before
// the camera (layer) starts following it. Giving empty rect will make sure the camera
// follows as soon as your player starts moving.
layerToFollow->runAction(followAction);
The code above will cause the layerToFollow to move whenever your player moves around. I hope this helps.
Related
i have been having trouble trying to set up wraparound in LibGDX using box2D, for example i want my player to appear at the left side of the screen after exiting the right side, but its not working here is my code:
public void setWraparound(){
//if player goes out of bounds vertically
if(body.getPosition().x < 0){
body.setTransform(new Vector2(4.8f, body.getPosition().y),body.getAngle());
}else if(body.getPosition().x > 4.8f){
body.setTransform(new Vector2(0, body.getPosition().y), body.getAngle());
}
//if player goes out of bounds Horizontally
if(body.getPosition().y < 0){
body.setTransform(new Vector2(body.getPosition().x,8f), body.getAngle());
}else if(body.getPosition().y > 8f){
body.setTransform(new Vector2(body.getPosition().x,0), body.getAngle());
}
}
Then i call the method in my GameStage class like this:
public GameStage() {
setUpWorld();
setupCamera();
setupTouchControls();
player.setWraparound();
renderer = new Box2DDebugRenderer();
}
anyone to help me out?
The place where you call your setWraparound method is wrong. You need to call it after a collision of the player with screen border happens. I suggest you do the following
Create static bodies for each screen border (you could use for example EdgeShape for that)
Add a ContactListener to your box2D world and check in the beginContact method if player & wall do touch.
Now after touch was detected call your method setWraparound
Alternatively you could create a Sensor that matches the screen size and detect if player touches the sensor borders. Or you could just check every frame your player's x/y positions and see if they are out of the screen, but it is better to use box2D collision detection.
I have the following function in a scene that extends citrus.core.starling.StarlingState - it loads the PlayerRun animation and displays it on the screen. For the most part, this code works: I see the sprite on the screen (it's running in place).
protected final override function DrawScene ():void
{
Player = new CitrusSprite ( "Player" );
Player.velocity = [60, 0]; // Doesn't seem to have an effect
Player.x = 40;
Player.y = 40;
var oClip:MovieClip = new MovieClip ( Resources.getTextures (
"PlayerRun" ), 24 );
Player.view = oClip;
add ( Player );
}
I'm not sure how I'm supposed to use the velocity property - there's no documentation for it and no matter what numbers I use in the code above, it doesn't change the display: the animation plays but the sprite is stationary (it doesn't move horizontally as I would expect it).
Am I using the velocity property incorrectly? Does Citrus support sprite velocity or is this something I'd have to implement myself?
As it turns out, CitrusSprite has a property, updateCallEnabled that's false by default and disables calls to update(). Once I set this property to true, the code started working as expected.
I haven't used Citrus yet, but looking at the source code it should work the way you've gone about it assuming that the update method is called on your player:
You can review the way the velocity property works at these locations:
The getter and setter for velocity.
The update loop for CitrusSprite.
MathVector, the type used for velocity internally.
I suspect you need to add the player to something that will queue it for updating.
Hey everyone so I am working on a fishing pole and I created a hook in AS3 that the user controls when they touch the screen the playerHook is allowed to move anywhere on the screen in any direction that the user directs it to.
So what i want is for the hookLine to be attached to the hook and follow it everywhere also the hookLine to be attached to the fishing pole as well, but i want the hook line to of course act like one, in the way that when the user moves the Hook to the end of the screen then the hook line stretches with it and when it is moved back, the hook line contracts. Hope you understand what I'm trying to convey. Just basically how a fishing pole acts.
Here is the code that I am using for the user to control the playerHook :
In my Main Function:
//Add hook to stage
playerHook = new mcHook;
stage.addChild(playerHook);
playerHook.x = (stage.stageWidth / 2);
playerHook.y = (stage.stageWidth / 2);
//Event listeners
playerHook.addEventListener(Event.ENTER_FRAME, playerHookMove);
In my playerHookMove function:
private function playerHookMove(e:Event):void
{
var xCoord = playerHook.x - mouseX;
var yCoord = playerHook.y - mouseY;
playerHook.x = playerHook.x - (xCoord / 3.5);
playerHook.y = playerHook.y - (yCoord / 3.5);
}
If anyone has any idea on how to have the hookLine object do what I stated above i would really appreciate it. I have ideas such as scaling and transforming. But not too sure. Please help!
I am beginning to write a game in LibGDX, only just beginning. I have got a basic tile map loaded, a player sprite and can move the character around and the screen (camera) scrolls around - perfect.
I have two overlayed textures in the bottom right of the screen, a left and right arrow, which are used as the joypad to control the character. I position these in relation to the players.x position, which is always fixed to the centre of the screen. Cool so far .... As below:
/////////////////////////////////////////////////////////////////
private void renderJoypad(float deltaTime)
{
batch.draw(Assets.leftJoypad, blockman.position.x-14, 1, 3, 3);
batch.draw(Assets.rightJoypad, blockman.position.x-9, 1, 3, 3);
}
I am now trying to put the player's score in the top left of the screen. The score is made of a Bitmap font, as below.
font = new BitmapFont(Gdx.files.internal("fonts/minecrafter.fnt"),Gdx.files.internal("fonts/minecrafter.png"),false);
font.setScale(0.02f);
In my render() method I cam calling some other methods to update, like the positions of the
leftJoypad etc, as in renderJoypad(). I am also calling my draw font method to update the position of the score, however, when I scroll it is all jerky, and sometimes it shows less characters than there should be.
public void drawScore(float deltaTime)
{
font.draw(batch, "00000", blockman.position.x, 10);
}
I believe that I need to place the score (and any other on screen texts, HUD etc) into a stage, but I cannot understand how to get it working with my existing code.
My show method is as follows:
public void show()
{
//load assets class to get images etc
Assets Assets = new Assets();
//start logging Framerate
Gdx.app.log( GameScreen.LOG, "Creating game" );
fpsLogger = new FPSLogger();
//set the stage - bazinga
Gdx.input.setInputProcessor(stage);
//stage.setCamera(camera);
//stage.setViewport(480, 360, false);
batch = new SpriteBatch();
//load the Joypad buttons
loadJoypad();
//background image
loadBackground();
//sounds
jumpSound = Gdx.audio.newSound(Gdx.files.internal("sounds/slime_jump.mp3"));
//LOAD block man here
// load the map, set the unit scale to 1/16 (1 unit == 16 pixels)
loadMap();
//draw the score
font = new BitmapFont(Gdx.files.internal("fonts/minecrafter.fnt"),Gdx.files.internal("fonts/minecrafter.png"),false);
font.setScale(0.02f);
// create an orthographic camera, shows us 30x20 units of the world
camera = new OrthographicCamera();
camera.setToOrtho(false, 30, 20);
camera.update();
// create the Blockman we want to move around the world
blockman = new Blockman();
blockman.position.set(25, 8);
}
and my render() method is as follows:
public void render(float delta)
{
// get the delta time
float deltaTime = Gdx.graphics.getDeltaTime();
stage.act(deltaTime);
stage.draw();
// clear the screen
Gdx.gl.glClearColor(0.3f, 0.3f, 0.3f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderBackground(deltaTime);
batch = renderer.getSpriteBatch();
//updateBlockman(deltaTime);
blockman.update(deltaTime);
// let the camera follow the blockMan, x-axis only
camera.position.x = blockman.position.x;
camera.update();
// set the tile map rendere view based on what the
// camera sees and render the map
renderer.setView(camera);
renderer.render();
//start the main sprite batch
batch.begin();
// render the blockMan
renderBlockman(deltaTime);
renderJoypad(deltaTime);
drawScore(deltaTime);
batch.end();
fpsLogger.log();
}
I have tried to change the way things work with relation to the Spritebatch etc and just cannot seem to get it working as I require.
Can anyone suggest how I may approach getting a stage and actors to work, or a second camera or something to help me achieve a fixed score display in the corner.
Do I need to use Scene 2D or something - aahhh! My head is exploding....
I look forward and thank you in advance.
Regards
James
I have a couple of suggestions:
Check to see if you have setUseIntegerPositions set to true
(the default) when you draw your font. If you do, and you're scaling
it, then it can cause some odd effects similar to those that you
describe. Set it to false and see if it fixes the problem.
Reset your spritebatch's matrices before drawing the text, that way you won't need to adjust it for the scrolling.
I'd even go as far as to recommend not scaling the font if you can help it, because fonts often look a little odd after being scaled.
I have a problem and I have potential solution. But I wanted to confirm if there is an easy and simple way to solve my problem.
App type:
Isometric Game
Problem statement:
I am loading images in my flash app and have mouse events attached to them.
The images I load are prop images like vehicles, trees, buildings etc., and all of them are transparent.
Example: Red ball asset (please ignore the yellow background which I applied to describe the problem)
If I click on the actual image area (colored in red), then every thing works perfect
I don't want to trigger mouseevent when I click on empty image part (or transparent area, which I have shown in yellow color)
There is one way I know by creating masks in flash. I don't want to do it unless that is the final option left because I load image assets instead of flash assets and I don't want to create a new mask asset for all the assets
There is another method I was going to adopt by using getPixel method of Bitmap. Which is discussed here.
But there is another problem with this method.
I might be able to ignore the click event when I click on the empty part of the asset but if there is some other asset is behind the image in the same location, then I need to process the click event for the occluded image.
Well, thinking of solution to this problem takes me to the getObjectsUnderPoint where I can scan the occluded assets
Well, what you proposed as a solution is 100% valid. Just move the logic of determining what game object is clicked outside of that object.
Listen for MOUSE_DOWN/MOUSE_UP events at container which contains your game objects.
Catch an event
Check if the game object which is the target of this event is transparent at this point using BitmapData.getPixel32
If it is use getObjectsUnderPoint to find out all other game objects at this point
Find in a loop the first object which is not transparent at this point
Now you got the actual object which is hit.
One interesting solution is to use Sprite objects with the individual non-transparent pixels burnt onto them.
Suppose this is your Loader "complete" handler:
private function loaderCompleteHandler(event:Event):void
{
// Loader is not our child, we use a Sprite instead (below).
var loader:Loader = Loader(event.target);
var sprite:Sprite = new Sprite();
addChild(sprite);
var w:Number = loader.content.width;
var h:Number = loader.content.height;
// Use transparent bitmap.
var bitmapData:BitmapData = new BitmapData(w, h, true, 0);
bitmapData.draw(loader.content);
// Now burn the image onto the Sprite object, ignoring
// the transparent pixels.
for (var xPos:int = 0; xPos < w; xPos++) {
for (var yPos:int = 0; yPos < h; yPos++) {
var pixel32:uint = bitmapData.getPixel32(xPos, yPos);
var alpha:int = pixel32 >>> 24;
if (alpha != 0) {
sprite.graphics.beginFill(pixel32 & 0xFFFFFF, alpha / 0xFF);
sprite.graphics.drawRect(xPos, yPos, 1, 1);
sprite.graphics.endFill();
}
}
}
}
Essentially you want "empty" pixels that aren't clickable, and fully transparent pixels aren't quite the same thing. With this solution you get empty pixels.
Only problem is that this might be slow. Give it a shot.