for some reason the block is not moving when I tilt the screen, and I don't know what's wrong. Just to clarify, I set the cfg.accelerometer to true, but the cfg.compass to false. Here's the source code-
public void update()
{
x += velX;
y += velY;
//movement
//left
if (Gdx.input.isKeyPressed(Keys.LEFT))
{
velX = -speed;
}
//right
if (Gdx.input.isKeyPressed(Keys.RIGHT))
{
velX = speed;
}
//up
if (Gdx.input.isKeyPressed(Keys.UP))
{
velY = -speed;
}
//down
if (Gdx.input.isKeyPressed(Keys.DOWN))
{
velY = speed;
}
if (Gdx.input.isPeripheralAvailable(Input.Peripheral.Accelerometer))
{
velX = Gdx.input.getAccelerometerX();
velY = Gdx.input.getAccelerometerY();
}
//stop
if (!Gdx.input.isKeyPressed(Keys.LEFT) && !Gdx.input.isKeyPressed(Keys.RIGHT))
{
velX = 0;
}
if (!Gdx.input.isKeyPressed(Keys.UP) && !Gdx.input.isKeyPressed(Keys.DOWN))
{
velY = 0;
}
//collision with edges of screen
if (x <= 0)
{
x = 0;
}
if (x >= 1920 - width)
{
x = 1920 - width;
}
if (y <= 0)
{
y = 0;
}
if (y >= 1080 - height)
{
y = 1080 - height;
}
long recoveryElapsed = (System.nanoTime() - recoveryTimer)/1000000;
if (recoveryElapsed > 2000)
{
recovering = false;
recoveryTimer = 0;
}
System.out.println(lives+ " lives, recovering, "+recovering);
}
Help would be much appreciated, thanks. There are no tutorials that I have found with a working example shown, so I don't really know if what I am doing is correct, but I can't see anything wrong with it.
You are setting the Accel values, and then if the keys are not pressed you are setting them to 0 again. Do it like this:
//stop
if (!Gdx.input.isKeyPressed(Keys.LEFT) && !Gdx.input.isKeyPressed(Keys.RIGHT))
{
velX = 0;
}
if (!Gdx.input.isKeyPressed(Keys.UP) && !Gdx.input.isKeyPressed(Keys.DOWN))
{
velY = 0;
}
if (Gdx.input.isPeripheralAvailable(Input.Peripheral.Accelerometer))
{
velX = Gdx.input.getAccelerometerX();
velY = Gdx.input.getAccelerometerY();
}
Related
I am trying to get a circle to be able to jump and move left and right at the same time, but right now its either only jumping or moving forward at a time. Anyone know how to change my code to solve this? Thanks
float px,py,vx,vy,ax,ay;
boolean canJump = false;
void setup(){
size(600, 400);
ax = 0;
ay = .32;
vx = 0;
vy = 0;
px = 300;
py = 200;
}
int x = 50;
int y = 520;
void draw(){
background(0);
ellipse(px-15, py-30, 60, 60);
vx+=ax;
vy+=ay;
px+=vx;
py+=vy;
if( py > height ){
py = height;
vy = 0;
canJump = true;
}
player();
}
void player(){
fill(255);
rect(0, 550, 1000, 50);
}
void keyPressed(){
if(keyCode == RIGHT || key == 'd'){
px += 10;
}
if(keyCode == LEFT || key == 'a'){
px -= 10;
}
if(keyCode == UP){
if(canJump) {
vy = -10;
canJump = false;
}
}
}
So you can make your ball go both up and right or up and left by checking that both keys are pressed and then you can add to the velocity instead of the position to affect the trajectory of the ball. However, then you must slow down the x component of the velocity when it hits the ground, so I added a friction variable.
float px, py, vx, vy, ax, ay;
boolean canJump = false;
float bounce = 0.2;
float friction = 0.2;
void setup() {
size(600, 400);
ax = 0;
ay = .32;
vx = 0;
vy = 0;
px = 300;
py = 200;
}
int x = 50;
int y = 520;
void draw() {
background(0);
ellipse(px-15, py-30, 60, 60);
vx+=ax;
vy+=ay;
px+=vx;
py+=vy;
if ( py > height ) {
py = height;
vy = -bounce*vy;
vx = friction*vx;
canJump = true;
}
}
void keyPressed() {
if (keyCode == RIGHT && keyCode == UP) {
if (canJump) {
vy = -10;
vx += 5;
canJump = false;
}
} else if (keyCode == LEFT && keyCode == UP) {
if (canJump) {
vy = -10;
vx += -5;
canJump = false;
}
} else {
if (keyCode == RIGHT || key == 'd') {
vx += 5;
}
if (keyCode == LEFT || key == 'a') {
vx -= 5;
}
if (keyCode == UP) {
if (canJump) {
vy = -10;
canJump = false;
}
}
}
}
You can improve the implementation of your program by taking a look at processing's PVector class.
PVector pos;
PVector vel;
PVector acc;
float friction = 0.3;
float bounce = 0.5;
float diameter = 60;
boolean canJump = false;
void setup() {
size(600, 400);
pos = new PVector(300, 200);
vel = new PVector(0, 1);
acc = new PVector(0, 0.32);
}
void draw() {
background(0);
circle(pos.x, pos.y, diameter);
vel.add(acc);
pos.add(vel);
if (pos.y + diameter/2 > height) {
pos.set(pos.x, height-diameter/2);
vel.set(vel.x*friction, -vel.y*bounce);
canJump = true;
}
}
void keyPressed() {
boolean right = keyCode == RIGHT || key == 'd';
boolean left = keyCode == LEFT || key == 'a';
boolean up = keyCode == UP || key == 'w';
if (up && right && canJump) {
vel.add(5, -10);
canJump = false;
} else if (up && left && canJump) {
vel.add(-5, -10);
canJump = false;
} else {
if (up && canJump) {
vel.add(0, -10);
canJump = false;
}
if (right) {
vel.add(5, 0);
}
if (left) {
vel.add(-5, 0);
}
}
}
This is probably a really stupid question but I am having trouble showing more that one copy of my class on the screen.
I have created an asteroid class that generates and moves an asteroid on the screen. Yet when I try and call multiple versions of this class in my main body, it still only shows one asteroid.
Main
int lrgAsteroids = 4;
Asteroid[] asteroid = new Asteroid[lrgAsteroids];
void setup() {
size(800,800);
for (int i = 0; i < lrgAsteroids; i++) {
asteroid[i] = new Asteroid();
asteroid[i].display();
}
}
void draw() {
background(0);
asteroid[0].move();
asteroid[1].move();
for (int i = 0; i < lrgAsteroids; i++) {
asteroid[i].move();
}
}
asteroid class.
class Asteroid {
PImage lrgAsteroid;
float xpos, ypos;
float yDirection;
float xDirection;
float radians = 0;
Asteroid() {
lrgAsteroid = loadImage("largeAsteroid.png");
xpos = random(0,710);
ypos = random(0,710);
int xDir = (int) random(2);
int yDir = (int) random(2);
if (xDir == 1) {
xDirection = 1;
} else if (xDir == 0) {
xDirection = -1;
}
if (yDir == 1) {
yDirection = 1;
} else if (yDir == 0) {
yDirection = -1;
}
}
void display() {
image(lrgAsteroid, xpos, ypos);
}
void move() {
background(0);
pushMatrix();
imageMode(CENTER);
translate(xpos, ypos);
rotate(radians);
image(lrgAsteroid, 0, 0);
popMatrix();
if (xpos <= 0) {
xpos = random(750,800);
} else if (xpos >= 800) {
xpos = random(0,100);
}
if (ypos <= 0) {
ypos = random(750,800);
} else if (ypos >= 800) {
ypos = random(0,100);
}
radians += 0.02;
xpos += xDirection;
ypos += yDirection;
}
}
Any help would be greatly appreciated.
The bug is very simple. Actually the display is clear, before an asteroid is drawn, because of background(0); in the method move(). It is sufficient to clear the background at the begin of draw().
Remove background(0); from the method move():
Asteroid() {
// [...]
void move() {
// background(0); <---- DELETE
pushMatrix();
imageMode(CENTER);
translate(xpos, ypos);
rotate(radians);
image(lrgAsteroid, 0, 0);
popMatrix();
if (xpos <= 0) {
xpos = random(750,800);
} else if (xpos >= 800) {
xpos = random(0,100);
}
if (ypos <= 0) {
ypos = random(750,800);
} else if (ypos >= 800) {
ypos = random(0,100);
}
radians += 0.02;
xpos += xDirection;
ypos += yDirection;
}
}
I think that somehow all the instances that your create get the same xDir and yDir or same xpos and ypos , can you print it so you can see if that's the problem ?
void setup() {
size(800,800);
for (int i = 0; i < lrgAsteroids; i++) {
asteroid[i] = new Asteroid();
// add these please to see what happens
System.out.println(asteroid[i].xDirection+" "+asteroid[i].yDirection);
}
}
void draw() {
background(0);
asteroid[0].move();
asteroid[1].move();
for (int i = 0; i < lrgAsteroids; i++) {
asteroid[i].move();
// add these please to see what happens
System.out.println(asteroid[i].xpos+" "+asteroid[i].ypos);
}
In this code i'm trying to make collision detection between the Enemy (that is constantly moving)and the Player. I set so that the Enemy will go in the oposite direction when hit. But when the two hit each other from different directions, there is a bug: the Enemy gets stuck in the Player until I move him. I know that instead of moving in the oppoite direction, I should change so it goes away from the Player, but I don't know how. Please help me!
public Enemy(float x, float y, ID id, Handler handler) {
super(x, y, id);
this.handler = handler;
vely = -6;
velx = -6;
}
protected void tick(LinkedList<Object> object) {
x += velx;
y += vely;
if(x <= 0){
if(velx < 0) velx = velx * -1;
}
if(y <= 0) {
if(vely < 0) vely = vely * -1;
}
if(x >= 605){
if(velx > 0) velx = velx * -1;
}
if(y >= 418) {
if(vely > 0) vely = vely * -1;
}
collision();
}
private void collision() {
for(int i = 0; i < handler.object.size(); i++) {
Object obj = handler.object.get(i);
if(obj.getId()== id.Player) {
if(getBound().intersects(obj.getBound())) {
velx = velx * -1;
vely = vely * -1;
}
}
}
}
protected void render(Graphics g) {
g.setColor(Color.BLACK);
g.fillOval((int)x, (int)y, 30, 30);
}
public Rectangle getBound() {
return new Rectangle((int)x, (int)y, 30, 30);
}
If the enemy is to the left of the player, set the enemy’s velx to negative, otherwise positive. Similarly for vely if enemy is above the player.
// on collision...
velx = Math.abs(velx);
vely = Math.abs(vely);
if ( enemy_left_of_player() )
velx = -velx;
if ( enemy_above_player() )
vely = -vely;
Exact left/above logic will depend on size of player (is it also 30 pixels?)
Am having issues trying to figure out how to translate or 'animate' my player's position to a new tile, this is what am doing :
if (input.right){
x += 1;
Right now am listening for key.inputs and then x++/x-- or y++/y-- on my players position that makes him move pixel by pixel, but i want my player to move exactly to the next tile(32 pixels) with one hit of the key with like a linear transition from the player's tile position to the next tile over time?
Something like (pseudo code i think..)
if input && walking false
walking = true
increment 1 by 1 32 ints to X over time?
after completed walking = false
I still cant even figure out the logic behind something like that.
An example is the movement in a game called Tibia.
Now Some bits of my code (player related)..
GAMECLASS >
public Game()
player = new Player(playerSpawn.x(), playerSpawn.y(), key);
player.init(level);
public void run()
....
render();
frames++;
....
public void update()
key.update();
player.update();
level.update();
public void render()
.....
int xScroll = ( player.x + 32) - screen.width / 2;
int yScroll = ( player.y + 32) - screen.height / 2;
level.render(xScroll, yScroll, screen);
player.render(screen);
for (int i =0; i < pixels.length; i++){
pixels[i] = screen.pixels[i];
}
SCREENCLASS >
......
public int[] pixels;
public int[] tiles = new int[VIEW_SIZE * VIEW_SIZE];
.....
public void renderTile(int xp, int yp, Tile tile){
xp -= xOffset;
yp -= yOffset;
for (int y = 0; y < tile.sprite.SIZE; y++){
int ya = y + yp;
for (int x = 0; x < tile.sprite.SIZE; x++){
int xa = x + xp;
if (xa < -tile.sprite.SIZE || xa >= width || ya < 0 || ya >= height) break;
if (xa < 0) xa = 0;
pixels[xa + ya * width] = tile.sprite.pixels[x + y * tile.sprite.SIZE];
}
}
}
//THIS IS THE METHOD CALLED TO RENDER THE PLAYER > SEE BELLOW AT THE PLAYER CLASS FOR THE CALL
public void renderMob(int xp, int yp, Mob mob){
xp -= xOffset;
yp -= yOffset;
for (int y = 0; y < 64; y++){
int ya = y + yp;
int ys = y;
for (int x = 0; x < 64; x++){
int xa = x + xp;
int xs = x;
if (xa < -64 || xa >= width || ya < 0 || ya >= height) break;
if (xa < 0) xa = 0;
int col = mob.getSprite().pixels[xs + ys * 64];
if (mob instanceof Chazer && col == 0xFF9b0000) col = 0xff54ff00;
if (col != 0xFFFF00FF) pixels[xa + ya * width] = col;
}
}
}
PLAYERCLASS >
public Player(int x , int y, Keyboard input){
this.x = x;
this.y = y;
this.input = input;
}
//PLAYER UPDATE
public void update(){
if (anim < 7500) anim++;
else anim = 0;
if (input.down) ya = 1;
if (input.up) ya = -1;
if (input.left) xa = -1;
if (input.right) xa = 1;
//CHECK BELLOW TO THIS MOVE METHOD
if (xa != 0){
move(xa, 0);
} else if(ya != 0){
move(0, ya);
}
}
clear();
}
//HERE ANIMATION AND CHOOSE WHAT SPRITE = WHERE PLAYER IS LOOKING AT
public void render(Screen screen){
if (dir == 0) {
sprite = Sprite.player_n;
if (walking) {
if (anim % 20 > 10){
sprite = sprite.player_n1;
} else {
sprite = sprite.player_n2;
}
}
}
if (dir == 1) {
sprite = Sprite.player_e;
if (walking) {
if (anim % 20 > 10){
sprite = sprite.player_e1;
} else {
sprite = sprite.player_e2;
}
}
}
if (dir == 2) {
sprite = Sprite.player_s;
if (walking) {
if (anim % 20 > 10){
sprite = sprite.player_s1;
} else {
sprite = sprite.player_s2;
}
}
}
if (dir == 3) {
sprite = Sprite.player_w;
if (walking) {
if (anim % 20 > 10){
sprite = sprite.player_w1;
} else {
sprite = sprite.player_w2;
}
}
}
// ADDING OFFSET CUZ THE PLAYER IS DOUBLE THE SIZE OF THE TILE
int xx = x - 42;
int yy = y - 42;
screen.renderMob(xx, yy, sprite);
}
//THIS IS HOW I MOVE THE PLAYER
public void move(int xa, int ya){
if (xa != 0 && ya != 0){
move(xa, 0);
move(0, ya);
return;
}
if (xa > 0) dir = 1;
if (xa < 0) dir = 3;
if (ya > 0) dir = 2;
if (ya < 0) dir = 0;
if(!collision(xa, 0)){
x += xa;
}
if(!collision(0, ya)){
y += ya;
}
}
Thanks alooot!
**Run method!
public void run() {
long xlastTime = System.nanoTime();
long timer = System.currentTimeMillis();
final double xns = 1000000000.0 / 60.0;
double delta = 0;
int frames = 0;
requestFocus();
while(running){
long xnow = System.nanoTime();
delta += (xnow-xlastTime) / xns;
xlastTime = xnow;
while (delta >= 1) {
update();
delta--;
}
render();
frames++;
if (System.currentTimeMillis() - timer > 1000){
timer += 1000;
frame.setTitle(title + " | " + frames + " fps");
frames = 0;
}
}
stop();
}
What I would do is declare two int fields in the player class:
private float xToMove = 0;
private float yToMove = 0;
Then, under your input event:
if (input.down && yToMove == 0)
yToMove = -32;
if (input.up && yToMove == 0)
yToMove = 32;
if (input.left && xToMove == 0)
xToMove = -32;
if (input.right && xToMove == 0)
xToMove = 32;
And finally, in your Player class's update method:
public void update()
{
if (xToMove > 0)
{
xToMove--;
x++;
}
if (xToMove < 0)
{
xToMove++;
x--;
}
if (yToMove > 0)
{
yToMove--;
y++;
}
if (yToMove < 0)
{
yToMove++;
y--;
}
}
Of course this is simplified a bit but the concept is there
EDIT: to change the speed. Note that xToMove and yToMove have been changed to floats.
You can use a float to represent the amount of time 1 move takes
float period = 1000; //The time one move takes in milliseconds
Somewhere you should calculate the number of pixels to be moved each frame. You could make a calculateSpeed() method or just throw it into the constructor or something. Depends on if you want speed to change during the game.
float speed = 32f / (fps * (period / 1000f)); //fps should be obtained dynamically and should be a float
Then when you update you should do this:
if (xToMove > 0)
{
xToMove -= speed;
x += speed;
if (xToMove <= 0)
{
//Set these guys to nice even numbers to prevent problems
xToMove = 0;
x = (float) Math.round(x);
}
}
Also make sure that x and y are floats.
EDIT 2: fps
int frames = 0;
int fps = 60;
requestFocus();
while(running){
long xnow = System.nanoTime();
delta += (xnow-xlastTime) / xns;
xlastTime = xnow;
while (delta >= 1) {
update();
delta--;
}
render();
frames++;
if (System.currentTimeMillis() - timer > 1000){
timer += 1000;
fps = frames;
frame.setTitle(title + " | " + fps + " fps");
frames = 0;
}
}
stop();
I'm using java with slick2d library and trying to move tile by tile with dynamic speed. I have tried a couple methods but none of them can move with dynamic speed between the tiles. Can someone help me with that and give some examples?
edit:
this two methods have I tried
move with out delta
movementSpeed = 2;
//decide direction
if(targetX != x)
{
animation.update(delta);
if(originalX < targetX)
x += movementSpeed;
else if(originalX > targetX)
x -= movementSpeed;
}
if(targetY != y)
{
animation.update(delta);
if(originalY < targetY)
y += movementSpeed;
else if(originalY > targetY)
y -= movementSpeed;
}
lerp
public static float lerp(float start, float stop, float t)
{
if (t < 0)
return start;
return start + t * (stop - start);
}
public void move(long delta)
{
if (procentMoved == 0)
{
if (getSpeed(targetX, targetY) != 0)
{
movementSpeed = getSpeed(targetX, targetY);
} else
{
targetX = originalX;
targetY = originalY;
}
}
if (procentMoved < 1)
{
animation.update(delta);
// movementSpeed = getSpeed(targetX, targetY);
procentMoved += movementSpeed;
} else if (procentMoved > 1)
{
animation.update(delta);
//TODO fix bouncing bug
procentMoved = 1;
}
+ movementSpeed);
x = lerp(originalX, targetX, procentMoved);
y = lerp(originalY, targetY, procentMoved);
if (x == targetX)
;
originalY = x;
if (y == targetY)
;
originalY = y;
}
It seems as if this could be your issue. Your if statements are just closing and not really doing its part. Also, you're variables are mixed up as well.
if (x == targetX)
; // This will skip the If statement
originalY = x;
if (y == targetY)
; // This will skip the If statement
originalY = y;
}
In all reality you're saying
orginalY = x; // Y = X?
orginalY = y; // Y = Y
Please do not take this to heart. I'm still having this issue as well, however I'm having to do some corrections and auto placements in order for this to work correctly.