I have been having this a problem for a while now and I just can't find a solution on how to fix it.
I have a character animation in my game, which works perfectly fine, except for the fact that, when I exit the app and enter it back without closing it, it simply disappears. By "disappearing", I don't mean it is just invisible, because if it was, the collision detection would still apply, but it doesn't.
I am using a custom animation class which looks like this:
public class Animation {
private Array<TextureRegion> frames;
private float maxFrameTime;
private float currentFrameTime;
private int frameCount;
private int frame;
public Animation(TextureRegion region, int frameCount, float cycleTime){
frames = new Array<TextureRegion>();
int frameWidth = region.getRegionWidth() / frameCount;
for(int i=0; i<=frameCount; i++)
frames.add(new TextureRegion(region, i * frameWidth, 0, frameWidth, region.getRegionHeight()));
this.frameCount = frameCount;
maxFrameTime = cycleTime / frameCount;
frame = 0;
}
public void update(float dt){
currentFrameTime +=dt;
if(currentFrameTime > maxFrameTime) {
frame++;
currentFrameTime = 0;
}
if(frame >= frameCount)
frame = 0;
}
public TextureRegion getFrame(){
return frames.get(frame);
}
}
I have heard about a function called "onPause", but I don't know how to access it. Even if I could, what would I write in there to fix my problem? I am not using GDX's "Screen", but a custom made "State" class.
EDIT: Here is my character movement code:
if(isAlive)
birdAnimation.update(dt);
if (position.y > 0 && isAlive) {
velocity.add(0, GRAVITY * dt);
}
velocity.scl(dt);
if(isAlive) {
position.add(MOVEMENT * dt, velocity.y);
velocity.scl(1 / dt);
}
if (position.y < 0)
position.y = 0;
if(position.y >= 1300 - sprite.getHeight())
position.y = 1300 - sprite.getHeight();
Related
I am using Libgdx to create a simple pong game with JAVA and when using two rectangles as my objects that will be colliding (ball and paddle/player) the ball often goes through my paddle, though sometimes it works and bounces back when it overlaps with each other.
I've tried doing it without using Rectangle.Overlap() but the same issue arises (if not worse).
Here is what my "Ball" class looks like :
Vector2 position;
Vector2 velocity;
Player player;
boolean gameStart = false;
public static final String TAG = Ball.class.getName();
public Ball() {
player = new Player();
init();
}
public void init(){
position = new Vector2(100,100);
velocity = new Vector2();
}
private void ballKick(){
Random random = new Random();
float angleX = MathUtils.PI2 * random.nextFloat();
float angleY = MathUtils.PI * random.nextFloat();
velocity.x = Constants.BALL_KICK_VELOICTY * MathUtils.cos(angleX);
velocity.y = Constants.BALL_KICK_VELOICTY * MathUtils.sin(angleY);
}
public void update(float delta, Viewport viewport){
if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE) && gameStart == false){
ballKick();
gameStart = true;
if (velocity.y < 100){
velocity.y = 100;
}
}
position.mulAdd(velocity,delta);
collision(viewport);
}
public void render(ShapeRenderer renderer){
renderer.setAutoShapeType(true);
renderer.setColor(Constants.BALL_COLOR);
renderer.set(ShapeRenderer.ShapeType.Filled);
renderer.circle(position.x,position.y,Constants.BALL_RADIUS,Constants.BALL_SEGMENTS);
{
private void collision(Viewport viewport){
// WALL COLLISION
//Bottom Side
//Top Side
if (position.y + Constants.BALL_RADIUS > viewport.getWorldHeight()){
position.y = viewport.getWorldHeight() - Constants.BALL_RADIUS;
velocity.y = -velocity.y;
}
// Left Side
if (position.x - Constants.BALL_RADIUS < 0){
position.x = Constants.BALL_RADIUS;
velocity.x = -velocity.x ;
}
// Right Side
if (position.x + Constants.BALL_RADIUS > viewport.getWorldWidth()){
position.x = viewport.getWorldWidth() - Constants.BALL_RADIUS;
velocity.x = -velocity.x ;
}
//PLAYER COLLISION
Rectangle ballBounds = new Rectangle(position.x - Constants.BALL_RADIUS,position.y - Constants.BALL_RADIUS,Constants.BALL_RADIUS * 2, Constants.BALL_RADIUS * 2);
Rectangle playerBounds = new Rectangle(player.position.x , player.position.y , Constants.PLAYER_WIDTH, Constants.PLAYER_HEIGHT);
if (ballBounds.overlaps(playerBounds)){
position.y = player.position.y + Constants.BALL_RADIUS + Constants.PLAYER_HEIGHT;
velocity.y = -velocity.y;
Gdx.app.log(TAG, "It overlapped");
}
}
I don't understand why it doesn't work properly as I have used this method in a different game and it seemed to work. Any help would be appreciated.
Edit:
I forgot to update the player in the ball class so the ball only knew it's starting position and thus only bounced off when it happened to land on the paddles starting position whether my paddle was still there or not. It is working now, thank you for the suggestions!
So, as the title reads I am trying to add offsets to my java game. I was given a tip by a friend that I need to minus the offset from where I render the tiles onto my screen.
So I created a random world generator and did the offset thing, but I ran into a problem.
My Code:
public void generateMap(Graphics g) {
block = seed.nextInt(2);
//Render Dirt
if(block == 0) {
g.drawImage(Assets.dirt, x - GameState.xOffset, y - GameState.yOffset, null);
x += 32;
}
//Render Grass
if(block == 1) {
g.drawImage(Assets.grass, x - GameState.xOffset, y - GameState.yOffset, null);
x += 32;
}
//Check Where the X is
if(x > xFinish) {
if(y < yFinish) {
x = xStart;
y += 32;
}
}
}
looks simple enough right? after I do that I create code to add one to the offset every time I loop around:
public void tick() {
xOffset += 1;
}
So after that is done I run it but it does this:
is there any simple way I can fix this so that it appears that the screen "scrolls" to the left?
Is there any simple way I can fix this...
Probably not. Games are complicated. Don't let that dissuade you.
You are generating your game world and drawing in the same methods - you don't want to do this. Separation of responsibility is very important - you don't want a whole bunch of code in one spot doing the same thing. In this case, the functionality to generate the world and the drawing code need to be split.
For the world generation, generate the game world once, and persist it to storage using whatever format you like. Keep this away from the drawing code - it has no place there.
For representing blocks in your world, consider something like this:
class Block {
public BlockType getType() {
return type;
}
public int getxPosition() {
return xPosition;
}
public int getyPosition() {
return yPosition;
}
// hashCode(), equals(), etc omitted, they should be implemented
public static enum BlockType {
Dirt(Assets.dirt),
Grass(Assets.grass);
private final BufferedImage image;
BlockType(BufferedImage image) {
this.image = image;
}
public BufferedImage getImage() {
return image;
}
}
private final BlockType type;
private final int xPosition;
private final int yPosition;
private Block(BlockType type, int xPosition, int yPosition) {
this.type = type;
this.xPosition = xPosition;
this.yPosition = yPosition;
}
public static Block getInstance(BlockType type, int xPosition, int yPosition) {
return new Block(type, xPosition, yPosition);
}
}
You can then use Block.getInstance() to generate a map once, like this:
class GameState {
private final int WORLD_SIZE = 1024;
private Block[][] _world = new Block[WORLD_SIZE][WORLD_SIZE];
private static Random seed = new Random();
public void generateMap() {
int blockTypeLength = Block.BlockType.values().length;
for (int x = 0; x < WORLD_SIZE; x++) {
for (int y = 0; y < WORLD_SIZE; y++) {
int blockType = seed.nextInt(blockTypeLength);
_world[x][y] = Block.getInstance(Block.BlockType.values()[blockType], x, y);
}
}
}
public Block[][] getMap() {
return _world; // not thread safe, shares internal state, all the usual warnings
}
This obviously isn't the only way to generate a world - you would probably generate a world and save, then load from disk in later games (unless it was a short lived game - I don't know, that's your call).
Once you've got the world sorted out, you'd move on to a different module that would handle drawing. Assume GameState has two fields playerX and playerY that represent the player's coordinates in the game world (note: direct fields like this are bad practice, but used to simplify this example):
public void paintComponent(Graphics g) {
super.paintComponent(g);
Block[][] screen = new Block[16][16]; // declare a screen buffer to draw
// Assumes player is in the center of the screen
int screenRadiusX = GameFrame.Assets.SCREENBOUNDS_X / 2 / blockSize;
int screenRadiusY = GameFrame.Assets.SCREENBOUNDS_Y / 2 / blockSize;
for (int x = state.playerX - 8, xS = 0; x < state.playerX + 8; x++, xS++) {
for (int y = state.playerY - 8, yS = 0; y < state.playerY + 8; y++, yS++) {
screen[xS][yS] = world[x][y];
}
}
for (int x = 0; x < screen.length; x++) {
for (int y = 0; y < screen.length; y++) {
Block current = screen[x][y];
g.drawImage(current.getType().getImage(),
x * blockSize, // blockSize is the pixel dimension of
y * blockSize,
null
);
}
}
}
If this helps, then great! I'm glad I was able to help. If not, or if some ideas are still unclear, then I would consider perhaps running through a tutorial or book that walks you through making a game. Don't forget to learn the platform you're coding on during such a process.
I want to implement a kind of drums. For every hit I want to play a song. So I need to detect every "hit" and the position. before I start implementing a function who will analyse the positions and detect "hits" I want to be sure that there is no other solution, so is there any event, gesture detection who allow me to detect that ?
As far as I know there is no "event" that is defined natively other than stream callbacks which are called when you receive data such as the joint positions and depth image which should be enough to get you started.
I would take a look at this:https://code.google.com/p/kineticspace/ in order to know what to expect or how to proceed with your own code.
Once you manage to get the skeleton data just find where the hand is at that time, put a threshold to its position and start tracking for a certain amount time and see if its movement path fits your pattern for a particular gesture such as "translation in y direction for x amount of seconds". Then you have very simple "hit" gesture detection. This can get as complex as you need, but there is not much to it at the basics in terms of what you receive from the library side.
Good luck.
I made a drum kit with the Kinect using this is a wonderful class for placing and using boxes in Kinect.
Import Libraries:
import processing.opengl.*;
import SimpleOpenNI.*;
Use something like this bit of code inside your Setup()
myTrigger = new Hotpoint(200, 10, 800, size);
Use the methods inside your draw()
if(myTrigger.currentlyHit()) {
myTrigger.play();
println("trigger hit");
}
Use the following methods inside this class!
class Hotpoint {
PVector center;
color fillColor;
color strokeColor;
int size;
int pointsIncluded;
int maxPoints;
boolean wasJustHit;
int threshold;
Hotpoint(float centerX, float centerY, float centerZ, int boxSize) {
center = new PVector(centerX, centerY, centerZ);
size = boxSize;
pointsIncluded = 0;
maxPoints = 1000;
threshold = 0;
fillColor = strokeColor = color(random(255), random(255), random(255));
}
void setThreshold( int newThreshold ){
threshold = newThreshold;
}
void setMaxPoints(int newMaxPoints) {
maxPoints = newMaxPoints;
}
void setColor(float red, float blue, float green){
fillColor = strokeColor = color(red, blue, green);
}
boolean check(PVector point) {
boolean result = false;
if (point.x > center.x - size/2 && point.x < center.x + size/2) {
if (point.y > center.y - size/2 && point.y < center.y + size/2) {
if (point.z > center.z - size/2 && point.z < center.z + size/2) {
result = true;
pointsIncluded++;
}
}
}
return result;
}
void draw() {
pushMatrix();
translate(center.x, center.y, center.z);
fill(red(fillColor), blue(fillColor), green(fillColor),
255 * percentIncluded());
stroke(red(strokeColor), blue(strokeColor), green(strokeColor), 255);
box(size);
popMatrix();
}
float percentIncluded() {
return map(pointsIncluded, 0, maxPoints, 0, 1);
}
boolean currentlyHit() {
return (pointsIncluded > threshold);
}
boolean isHit() {
return currentlyHit() && !wasJustHit;
}
void clear() {
wasJustHit = currentlyHit();
pointsIncluded = 0;
}
}
So I made a java game with jumping some time ago and I used this method for all the moving:
double height = 0, speed = 4;
public static final double gravity = 9.81;
double x = 25;
int a;
int y = (int) (500-(height*100));
boolean left = false, right = false, up = false;
public void the_jump() {
long previous = 0, start = 0;
while(true){
start = System.nanoTime();
if(previous != 0 && up){
double delta = start - previous;
height = (height + (delta/1000000000) * speed);
speed -= (delta/1000000000) * gravity;
y = (int) (500-(height * 100));
}
if(left){
x-= 3;
}
if(right){
x+= 3;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(height < 0){
height = 0;
speed = 4;
up = false;
}
previous = start;
}
}
Now It was okay when I did it all with just JComponents and such, but now when I want to implement it in a Slick enviroment, it fails.
The problem is in the while(true){} loop. If I change it against for(int i = 0; i < 1; i++) loop, then moving left and right will work. But this will not work for the jumping. I could increase the i < 1 to i < 5 and then the jump will work, but at the cost of a lot of performance.
So how would people implement this in slick? Right now I am calling the the_jump(); out in my public void update(GameContainer gc, int t) throws SlickException method, and if I use the while loop, the game will crash.
Slick already loop on update(GameContainer gc, int delta), you have to put all the code located in your while loop into the update method.
Moreover, you get the delta time between two update as parameter, and so not have to calculate it.
Feel free to ask me more question ;)
Off Topic, do you know if Slick2d is still maintain ? I switch to libGDX a few month ago, and I really advice you to test it, it's soooo fun :)
I'm trying to learn making games with android using sensors. What I'm trying to do is to make a ball moving in the screen using acceleration sensor. Actually, I did some part of it. The ball moves in the screen when acceleration of x and y changes. But my problem is that it does not look smooth. It looks like the ball is not drawn on the screen in continuous paths. I use the SurfaceView class for this app and I made the drawing on different thread than the main thread.
Below part of code is from my MainActivity class and it is the sensor related part:
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
long actualTime = System.currentTimeMillis();
long delta_t = actualTime - lastUpdate;
lastUpdate = actualTime;
ax = event.values[0];
ay = event.values[1];
if (ax > 0) {
isleft = true;
delta_x = (float) (0.005 * ax * delta_t * delta_t);
}
if (ax < 0) {
isleft = false;
delta_x = (float) (-0.005 * ax * delta_t * delta_t);
}
if (ay > 0) {
isdown = true;
delta_y = (float) (0.005 * ay * delta_t * delta_t);
}
if (ay < 0) {
isdown = false;
delta_y = (float) (-0.005 * ay * delta_t * delta_t);
}
getBallPos();
}
}
private void getBallPos() {
delta_x /= 10000;
delta_y /= 10000;
for (int i = 1; i <= 10000; i++) {
if (isleft)
ballview.setX_loc(ballview.getX_loc() - delta_x);
if (!isleft)
ballview.setX_loc(ballview.getX_loc() + delta_x);
if (isdown)
ballview.setY_loc(ballview.getY_loc() + delta_y);
if (!isdown)
ballview.setY_loc(ballview.getY_loc() - delta_y);
}
}
Below part of code is from my BallGame class that extends SurfaceView and I do the drawings on a different thread:
#Override
public void run() {
// TODO Auto-generated method stub
while (isItOk) {
if (!holder.getSurface().isValid()) {
continue;
}
canvas = holder.lockCanvas();
canvas.drawARGB(255, 150, 150, 10);
// canvas.drawLine(lineStartX, lineStartY, lineEndX, lineEndY,
// paint);
checkBoundaries();
canvas.drawBitmap(ball, x_loc, y_loc, null);
holder.unlockCanvasAndPost(canvas);
}
}
private void checkBoundaries() {
if (x_loc > canvas.getWidth() - ballWidth) {
x_loc = canvas.getWidth() - ballWidth;
}
if (y_loc > canvas.getHeight() - ballHeight) {
y_loc = canvas.getHeight() - ballHeight;
}
if (x_loc < 0) {
x_loc = 0;
}
if (y_loc < 0) {
y_loc = 0;
}
}
Thank you in advance.
I think that there are two problems:
First is, that you are updating the ball position in onSensorChanged method. This method is called by the system and it is not guaranteed that the calling is done in constant frequency. In this case is ball movement depended on these calls. I think the better way would be to store the last ax and ay as a variables which would be accessible by both onSensorChanged method for writing values and drawing thread for reading. Then you can compute ball position in drawing thread, which could redraw canvas with constant frequency.
This brings us to the second problem which is drawing thread while loop. It is not controlled how often is the canvas redrawn. It is big load for system. Better way is to choose the refresh rate (for example 50 frames per second) and update the drawing at this frequency. It could be done at the end of the while loop, where Thread.sleep() function can be called. You can measure when the frame drawing started long frameStartTime = System.currentTimeMillis() at the start of the while loop and then call at the end of the while loop:
long sleepTime = refreshInterval-(System.currentTimeMillis()-frameStartTime );
if (sleepTime > 0) {
Thread.sleep(sleepTime);
}
(for 50 fps is refreshInterval = 1000/50 = 20 ms).
This calling sleeps the thread for the time of frame refresh interval minus time which was used to draw the ball. When you select adequate refresh rate system load will be lower and will have more time for redrawing.