I am creating a character which moves, it moves upwards fine but when it moves side ways it is extremly slow. Here is the movement code:
p.getPosition().y += playerSpeed;
This is the code for handling input:
World world;
Player p;
WorldHandler wh;
public boolean touchUp(int screenX, int screenY, int pointer, int button)
{
p = world.getPlayer();
wh = new WorldHandler(world);
if(screenX >= Gdx.graphics.getWidth() / 2) // Right side of the screen
{
p.getVel().x = wh.playerSpeed;
}
if(screenX <= Gdx.graphics.getWidth() / 2) // Left side of the screen
{
p.getVel().x = -wh.playerSpeed;
}
return false;
}
Thanks for any help! :)
I fixed it well i fixed it in a kind of cheaty way i guess. Instead of doing:
if(screenX >= Gdx.graphics.getWidth() / 2) // Right side of the screen
{
p.getVel().x = wh.playerSpeed;
}
if(screenX <= Gdx.graphics.getWidth() / 2) // Left side of the screen
{
p.getVel().x = -wh.playerSpeed;
}
I did this: if(screenX >= Gdx.graphics.getWidth() / 2) // Right side of the screen
{
p.getVel().x = 12;
}
if(screenX <= Gdx.graphics.getWidth() / 2) // Left side of the screen
{
p.getVel().x = -12;
}
And also the y movement i fixed it to a more smoother movement style thanks to Fish, here's the code: p.getPosition().y += playerSpeed * Gdx.graphics.getDeltaTime();
That's all for me! :)
Related
I'm creating a game where the movement mechanics are meant to work like this: tap/hold the right side of the screen to accelerate in the direction you're facing and swipe either left or right on the left side of the screen to rotate. It works well enough until the player tries to rotate with a second finger while accelerating with the first. The pan method seems to still run with the second finger but very infrequently and the gdx.input.getX(i) if statements don't fire off. I'm using the pan method of the GestureDetector class. Here's a video: https://www.youtube.com/watch?v=FmHI81ByPmU&feature=youtu.be
I looked at this similar question: libgdx multiple pan events but the answers did not work for me, setting pan to return false did nothing, and the controls aren't related to buttons so I can't change the method into touchDown
The pan method by itself:
#Override
public boolean pan(float x, float y, float deltaX, float deltaY) {
for(int i = 0 ; i < 2 ; i++){//In case they drag wit second finger
if(Gdx.input.isTouched(i) && Gdx.input.getX(i) < Gdx.graphics.getWidth() / 2){
if(Gdx.input.getDeltaX(i) < - 3){
directionListener.onRight();
System.out.println(">");
}
if(Gdx.input.getDeltaX(i) > 3) {
directionListener.onLeft();
System.out.println("<");
}
finger = i;//used to stop body from rotating when the finger rotating it is lifted
System.out.println(i + " = " + Gdx.input.getX(i));
}
}
//Can't replace with touchdown because it does not override method from superclass
return super.pan(x, y, deltaX, deltaY);
}
The entire class:
package com.doppelganger.spacesoccer.Helpers;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.input.GestureDetector;
public class SimpleDirectionGestureDetector extends GestureDetector{
public static int finger = 10;
public interface DirectionListener {
void onLeft();
void onRight();
}
public SimpleDirectionGestureDetector(DirectionListener directionListener) {
super(new DirectionGestureListener(directionListener));
}
private static class DirectionGestureListener extends GestureDetector.GestureAdapter {
DirectionListener directionListener;
DirectionGestureListener(DirectionListener directionListener){
this.directionListener = directionListener;
}
#Override
public boolean pan(float x, float y, float deltaX, float deltaY) {
for(int i = 0 ; i < 2 ; i++){//In case they drag with second finger
if(Gdx.input.isTouched(i) && Gdx.input.getX(i) < Gdx.graphics.getWidth() / 2){
if(Gdx.input.getDeltaX(i) < - 3){
directionListener.onRight();
System.out.println(">");
}
if(Gdx.input.getDeltaX(i) > 3) {
directionListener.onLeft();
System.out.println("<");
}
finger = i;//used to stop body from rotating when the finger rotating it is lifted
System.out.println(i + " = " + Gdx.input.getX(i));
}
}
//Can't replace with touchdown because it does not override method from superclass
return super.pan(x, y, deltaX, deltaY);
}
}
}
I see the problem, you are ignoring the input when you touch the right side of the screen. Here's the line:
if(Gdx.input.isTouched(i) && Gdx.input.getX(i) < Gdx.graphics.getWidth() / 2){
You could verify Gdx.input.getX(i) < Gdx.graphics.getWidth() / 2 inside on another if statement and add an else statement to check the right side, something like this:
if(Gdx.input.isTouched(i)) {
if (Gdx.input.getX(i) < Gdx.graphics.getWidth() / 2) {
// POINTER ON LEFT SIDE - SAME CODE
if(Gdx.input.getDeltaX(i) < - 3) {
directionListener.onRight();
System.out.println(">");
}
if(Gdx.input.getDeltaX(i) > 3) {
directionListener.onLeft();
System.out.println("<");
}
finger = i; //used to stop body from rotating when the finger rotating it is lifted
System.out.println(i + " = " + Gdx.input.getX(i));
} else {
// POINTER ON RIGHT SIDE - NEW CODE
System.out.println("Right side");
}
}
i'm trying to create a minigame with circles rotating around circles
however, i have a problem when i shoot the circle and it hits the second circle it doesnt continue the angle but "jumping" to the other side i'm sure it something with the angle var that should reset or something. can you help me im getting nervous around here... :(
check the example
This is my code for the enter frame function that deals with the circles
public function UpdateCircles(e:Event):void
{
for (var i:int = 0; i < EnemySpriteVector.length; i++)
{
EnemySpriteVector[i].rotation += EnemySpriteVector[i].enemyspeed;
}
var rad:Number = angle * (Math.PI / 180); // Converting Degrees To Radians
if (IsplayerShoot)
{
playerSprite.x += Math.cos(rad) * PlayerCircleShootSpeed;
playerSprite.y += Math.sin(rad) * PlayerCircleShootSpeed;
for (var j:int = 0; j < EnemySpriteVector.length; j++)
{
if (EnemySpriteVector[j].hitTestPoint(playerSprite.x,playerSprite.y) && (EnemySpriteVector[j].IsCircleHit == false))
{
trace("hit");
EnemySpriteVector[j].IsCircleHit = true;
removeChild(EnemySpriteVector[0]);
EnemySpriteVector.splice(0, 1);
var EnemySprite:Sprite = new EnemySpriteClass();
EnemySpriteVector.push(EnemySprite);
addChild(EnemySprite);
EnemySprite.x = Math.random() * stage.stageWidth;
EnemySprite.y = Math.random() * stage.stageHeight;
IsplayerShoot = false;
}
}
}
else
{
playerSprite.x = EnemySpriteVector[0].x + EnemySpriteVector[0].radius * Math.cos(rad); // Position The Orbiter Along x-axis
playerSprite.y = EnemySpriteVector[0].y + EnemySpriteVector[0].radius * Math.sin(rad); // Position The Orbiter Along y-axis
angle += EnemySpriteVector[0].enemyspeed; // Object will orbit clockwise
playerSprite.rotation = (Math.atan2(playerSprite.y - EnemySpriteVector[0].y, playerSprite.x - EnemySpriteVector[0].x) * 180 / Math.PI); //only rotates the player circle itself
}
}
Looks like when the pink circle hits the green one it simply continues its rotation from where it left of. A quick solution would be to add 180 degrees to the angle. Keep in mind this will only work for static objects. If you want a more dynamic environment I would recommend using vectors (linear algebra). Vector math is really easy to understand and it hides a lot of complex trigonometry. You can start here :)
private function scrollStage():void
{
if (lastPosX != lastPosX)
{
canScrollStage = false;
}
else
if (lastPosX == lastPosX)
{
canScrollStage = true;
}
if (canScrollStage)
{
if (rightKey)
{
//move background left
//something.x +=(stage.stageWidth * 0.5) - character.x * 2;
}
else
if (leftKey)
{
//move backgrounf Roight
}
for (var b:int = 0; b < childrenOnStage; b++)
{
if (getChildAt(b).name == "enemy")
{
getChildAt(b).x +=(stage.stageWidth * 0.5) - character.x
}
}
ground.x += (stage.stageWidth * 0.5) - character.x
}
else
{
//move the background
}
// do this last, everything moves around object
character.x = stage.stageWidth * 0.5;
lastPosX = character.x;
}
Someone told me to move the objects around the player and then update the players x position.
This is what I've done by looking at a tutorial ("Cartoon Smart");
In my player class I have a reset function.
private var xSpeed:int;
private var resetPos:Point;
public function player()
{
addEventListener(Event.ADDED_TO_STAGE, onAdd)
}
private function onAdd(e: Event): void
{
xSpeed = 3;
resetPos = new Point(x, y);
}
public function reset():void
{
x = resetPos.x;
y = resetPos.y;
//trace(resetPos);
//trace(resetPos + "player");
}
When the player falls to death this function is called
private function playerFalls():void
{
if (character.y > stage.stageHeight)
{
//take life away and go back to check point or back to reset
character.x = stage.stageWidth * 0.5;
character.y = 20;
//goblin1.reset();
//goblin2.reset();
//goblin3.reset();
//stage.x = stage.stageWidth * 0.5;
//canScrollStage = false;
}
}
if I use
character.x = stage.stageWidth * 0.5;
Then my character ends up in the middle, but it will end up in the middle since the scroll function dictates the player to be in the center always.
character.x = (stage.stageWidth * 0.5) - 400;// moves him back
but if character falls off left of the screen then he is moved back.
Any one have a solution for this please?
My question is, I want to reset the player's x position to 300 and y position to 10;
But I can't do this because the stage shifts and the co ordinate system changes.
In order for the player to go back to the original coordinate of the stage, the stage must scroll.
That's my idea, or perhaps the ground and enemies must do the opposite?
I sincerely apologize for the late answer. Okay, so your saying that when the character falls you don't want the screen to scroll all the way back to the character's start position. What you need to do is find the start positions of your character and ground (as well as any other layers such as backgrounds etc). Then wherever your fall function comes into place simply set the character and background positions to their starting coordinates.
function fall(){
char.x=charStartX;
char.y=charStartY;
ground.x=groundStartX;
ground.y=groundStartY;
//etc
}
For example, let's say you have a check point. If player hits check point charResetPoint = 100. If player falls then set it's x pos to charResetPoint
But I can't move the players x position because it will always be stage.stageWidth/2 due to my code.
So in theory it will be difficult to make a resetPoint, because when I add goblin 1.x , it's x pos is 900, if I scroll right goblon1 x pos will change. Everythings x pos changes and so does the stages.
I can't get a grasp on the concept, sortlry
I am trying to build a RTS game with Flash and doing some basic testing. I come across this site teaching me dragging objects. I am modified the code to simulate moving the game world of the game while clicking on it. The center circle is the focus point / center of camera. The rectangle board represents the game world.
I tried to change the function boardMove to click and move according to mouseX and mouseY. But every time I click, the mouseX and mouseY becomes the center of the board, which is not what I wanted. I want to make it relative to the mouse position, but I could only make the board flickering, or moves with its top left corner.
Any suggestions would be appreciated.
// Part 1 -- Setting up the objects
var board:Sprite = new Sprite();
var myPoint:Sprite = new Sprite();
var stageWidth = 550;
var stageHeight = 400;
var boardWidth = 400;
var boardHeight = 300;
var pointWidth = 10;
this.addChild(board);
this.addChild(myPoint);
board.graphics.lineStyle(1,0);
board.graphics.beginFill(0xCCCCCC);
board.graphics.drawRect(0,0,boardWidth,boardHeight);
board.graphics.endFill();
board.x = (stageWidth - boardWidth) / 2;
board.y = (stageHeight - boardHeight) / 2;
myPoint.graphics.lineStyle(1,0);
myPoint.graphics.beginFill(0x0000FF,0.7);
myPoint.graphics.drawCircle(0,0,pointWidth);
myPoint.graphics.endFill();
myPoint.x = (stageWidth - pointWidth) / 2;
myPoint.y = (stageHeight - pointWidth) / 2;
// Part 2 -- Add drag-and-drop functionality - Better Attempt
stage.addEventListener(MouseEvent.MOUSE_DOWN, startMove);
function startMove(evt:MouseEvent):void {
stage.addEventListener(MouseEvent.MOUSE_MOVE, boardMove);
}
// Revised definition of pointMove in Part II of our script
function boardMove(e:MouseEvent):void {
board.x = checkEdgeX(board.mouseX);
board.y = checkEdgeY(board.mouseY);
e.updateAfterEvent();
}
stage.addEventListener(MouseEvent.MOUSE_UP, stopMove);
function stopMove(e:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_MOVE, boardMove);
}
// Part III -- Check for boundaries
function checkEdgeX(inX:Number):Number {
var x = stageWidth / 2 - boardWidth;
if (inX < x) {
return x;
}
x = stageWidth / 2;
if (inX > x) {
return x;
}
return inX;
}
function checkEdgeY(inY:Number):Number {
var y = stageHeight / 2 - boardHeight;
if (inY < y) {
return y;
}
y = stageHeight / 2;
if (inY > y) {
return y;
}
return inY;
}
One option is to determine the relative movement of the mouse and move the board accordingly; something like:
private Point lastPosition;
function startMove(...) {
lastPosition = null;
...
}
function boardMove(e:MouseEvent):void {
Point position = new Point(stageX, stageY);
if (lastPosition != null) {
Point delta = position.subtract(lastPosition);
board.x += delta.x; // NOTE: also try -= instead of +=
board.y += delta.y; // NOTE: also try -= instead of +=
e.updateAfterEvent();
}
lastPosition = position;
}
I have an animated MovieClip of a fly that spawns at a random location and moves across the screen by bouncing off the walls. But every time the animation starts over, it seems to "jump" to a random location. Here is the code I have for when it spawns:
private function beginClass(e:Event):void{
_root = MovieClip(root);
do {
xRandom = Math.floor(Math.random() * 500);
yRandom = Math.floor(Math.random() * 350);
this.x = xRandom;
this.y = yRandom;
} while (Math.abs(xRandom - mouseX) > 20 && Math.abs(yRandom - mouseY) > 20);
}
And this is the code for its movement:
//Bouncing the fly off of the walls
if(this.x >= stage.stageWidth-this.width){
//if the fly hits the right side
//of the screen, then bounce off
flyXSpeed *= -1;
}
if(this.x <= 0){
//if the fly hits the left side
//of the screen, then bounce off
flyXSpeed *= -1;
}
if(this.y >= stage.stageHeight-this.height){
//if the fly hits the bottom
//then bounce up
flyYSpeed *= -1;
}
if(this.y <= 0){
//if the fly hits the top
//then bounce down
flyYSpeed *= -1;
}
How do I fix it so that the fly continues moving in its appropriate path every time the animation starts over?
If I understand the problem correctly, when starting the animation you have to check if it has already been started before.
A simple boolean variable would do:
private var hasStarted:Boolean = false;
private function beginClass(e:Event):void{
_root = MovieClip(root);
if (!hasStarted) {
hasStarted = true;
do {
xRandom = Math.floor(Math.random() * 500);
yRandom = Math.floor(Math.random() * 350);
this.x = xRandom;
this.y = yRandom;
} while (Math.abs(xRandom - mouseX) > 20 && Math.abs(yRandom - mouseY) > 20);
}
}
This way it'll only execute the random placing code once.