I think that's a simple error, but I've crashed my mind thinking about it and I can't do it.
I don't know why when I jump with the player and collides with another rectangle (platform) the player appears above it.
for(RectangleMapObject rectangleObject : map.getLayers().get("platform").getObjects().getByType(RectangleMapObject.class)){
Rectangle rectangle = rectangleObject.getRectangle();
float x = rectangle.x;
float y = rectangle.y;
float width = rectangle.width;
float height = rectangle.height;
shapeRenderer.rect(x, y, width, height);
//TODO: Finish tile's physics
if(Intersector.overlaps(rectangle, nihanRect)) {
if (velocity.y > 0) {
nihan.getVelocity().y = 0;
nihan.getPosition().y = y - height - Constants.NIHAN_HEIGHT - 10;
nihan.setCollisions(false);
nihan.setAvailableJump(false);
} else {
nihan.getPosition().y = y + height - 0.5f;
nihan.setCollisions(true);
nihan.setAvailableJump(true);
if(Gdx.input.isKeyPressed(Input.Keys.Z)){
nihan.getPosition().y = y + height;
}
}
nihan.getVelocity().y = 0;
Gdx.app.log(TAG, "Collision produced!");
}else{
nihan.setCollisions(false);
}}
Sorry if my english is bad, I'm a spanish speaker.
Greetings!
When the player is standing -->
After jumping the player appears in the top of the platform
I changed variable "velocity.y" to "nihan.getVelocity.y"
Related
I have been coding a significantly simple game for my academic work in which the PNG bee sprite is meant to run away from the orange ball. If the bee collides with the orange ball, she dies. Apart from this, I intend to include a timer that keeps going onwards as the bee succeeds in running away from the ball. The ball moves automatically throughout the screen, whereas the bee bounces throughout the screen with the arrow keys and gravity.
I have come across some explanations towards collision detection upon the Processing forum, however I still don't understand how this event can occur in the cases of circles x circles collisions, rectangles x circles collisions, etc.
Please, excuse my messy code. Also, excuse my poor description of what I want to know.
This is what I see on the screen:
My code:
//background
PImage background;
// keys | keyboard
boolean upPressed = false;
boolean downPressed = false;
boolean leftPressed = false;
boolean rightPressed = false;
// bee player character
PImage charImage;
float charSpeed = 5.5;
float charX = 0;
float charY = 450;
float gravity = 1.5;
float vy = 0;
float bounce = -0.8;
// platforms
PImage bee;// bee
float beeX = 300;
float beeY = 490;
PImage hi; // hi
float hiX = 400;
float hiY = 300;
PImage ve; // ve
float veX = 420;
float veY = 440;
// more beehives
PImage beehive4;// beehive4
float bee4X = 120;
float bee4Y = 90;
PImage beehive5; // beehive5
float bee5X = 200;
float bee5Y = 300;
PImage beehive6; // beehive6
float bee6X = 30;
float bee6Y = 400;
PImage beehive7; // beehive7
float bee7X = 496;
float bee7Y = 90;
// enemy ball
float ballX = 100;
float ballY = 100;
float xspeed = 100;
float yspeed = 100;
//////
public void setup() {
size(600, 800);
noStroke();
smooth();
noFill(); // to adjust the image in the screen properly in fullscreen
//load beehives
bee = loadImage("beehive 1.png");
bee.resize(100, 100);
hi = loadImage("beehive 2.png");
hi.resize(100,100);
ve = loadImage("beehive 3.png");
ve.resize(100, 100);
// load more beehives
beehive4 = loadImage("beehive 4.png");
beehive4.resize(100, 100);
beehive5 = loadImage("beehive 5.png");
beehive5.resize(100, 100);
beehive6 = loadImage("beehive 6.png");
beehive6.resize(100, 100);
beehive7 = loadImage("beehive 7.png");
beehive7.resize(100, 100);
}
/*********** drawing section !***********/
public void draw() {
background(244, 240, 219);
noStroke();
// render beehives
image(bee, beeX, beeY);
image(hi, hiX, hiY);
image(ve, veX, veY);
// render more beehives
image(beehive4, bee4X, bee4Y);
image(beehive5, bee5X, bee5Y);
image(beehive6, bee6X, bee6Y);
image(beehive7, bee7X, bee7Y);
// render bee
charImage = loadImage("bee walk 3.png");
charImage.resize(200, 200);
vy += gravity; // it applies gravity to the bee sprite
charY += vy;
if(charY > height - 150 )
vy *= bounce; // bouncing bee
// Add the current speed to the location.
ballX = ballX + xspeed;
ballY = ballY + yspeed;
// Check for bouncing
if ((ballX > width) || (ballX < 0)) {
xspeed = xspeed * -1;
}
if ((ballY > height) || (ballY < 0)) {
yspeed = yspeed * -1;
}
// Display at x,y location
stroke(0);
fill(179, 98, 0);
ellipse(ballX, ballY,80,80);
// update keys
if (upPressed) {
charY--;
}
if (downPressed) {
charY++;
}
if (leftPressed) {
charX--;
}
if (rightPressed) {
charX++;
}
if(keyPressed){
if(keyCode == UP && charY > 0){
charY -= 30;
}
if(keyCode == DOWN && charY < height){
charY += 10;
}
if(keyCode == LEFT && charX > 0){
charX -= 30;
}
if(keyCode == RIGHT && charX < width){
charX += 10;
}
}
// render beecharacter on screen
image(charImage, charX, charY);
}
There mulitple ways to tackle the problem.
Collision detection can be coarse: less accurate but faster (and simpler) or detailed (e.g. pixel level precision) but slower (and more complex).
In terms of simple collision detection two options could rectangle or circle intersections.
Rectangle intersection can be implemented manually or using Rectangle's intersects() method.
Circle intersection is trivial: if the distance(dist()) between the 1st circle's center and 2nd circle's center is smaller than the two radii then they must intersect.
here's a basic example illustrating circle intersection:
// check collision: circle
if (dist(ballX, ballY, charX, charY) < charImage.width) {
// tint red to display collision: placeholder for subtracting bee health
tint(192, 0, 0);
}else{
noTint();
}
this condition can be added before this section in draw():
// render beecharacter on screen
image(charImage, charX, charY);
The collision detection is quite rough: not pixel perfect, but hopefully a good starting point. It should tint everything red if there's a collision.
I have two other small suggestions:
reducing xspeed, yspeed to 10 or smaller values will make the game more playable. 100px/frame is too fast for people and the bee will likely collide instantly before the users even has a chance to react.
intead of a boolean beeIsAlive sort of variable that immediately, with one ball hit switches to true also might be too harsh as a game rule. Consider something like int beeHealth = 100; and gradually reducing the health with each collision will make the game more playable.
I'm a beginner in coding and creating a castle defender game.
I'm trying to add bullet shooting to my code but I'm having a hard time implementing it to my project.
Here is the code I came up with for shooting the bullets downwards in the void draw() function
float bulletY = DefenderY; //bullet being set in player x position
float bulletX= DefenderX; //bullet set in player y position
rect(bulletX, bulletY, 8, 8); //creating the bullet
text("score: ", countA, 20, 80); //score counter not implemented yet
if (keyPressed && key==CODED && key == 's')// if the space bar is pressed //key press detection,
{
dropping = true; //boolean is now true when previously false
}
if(dropping == true){ if (bulletY<=400) // checking if the bullet is still within the frame
bulletY= bulletY + 1;} //boolean true then the rectangle should move from the player position
}
if(bulletY>=400){dropping = false; //when bullet hits game borders reset to player position
bulletY=DefenderY;
bulletX=DefenderX;}
However the rectangle bullet is not moving from the (DefenderY, DefenderY) position, it stays attached the the player, any help would be appreciated.
I will also post the whole code below if that helps with my question thanks.
class attackers{
float max = 400;
float min = 1;
float posx = (int)Math.floor(Math.random()*(max-min+1)+min);
float posy = 400;
float speed = 1;
}
attackers one, two, three, four;
float DefenderX= 100;
float DefenderY=100;
void setup()
{
one = new attackers();
two = new attackers();
three = new attackers();
four = new attackers();
size(400,400); //fairly large relative to objects
rectMode(CENTER); //set rect x,y to be the centre.
}
float gunX=40;
boolean dropping = false;
int countA = 0;
void draw()
{
background(#0000FF); //clear background
ellipse(DefenderX,DefenderY,20,20);//Draw player current position (x,y)
if ( abs(DefenderX - one.posx)<20 && abs(DefenderY-one.posy )<20 ||
abs(DefenderX - two.posx)<20 && abs(DefenderY-two.posy )<20 ||
abs(DefenderX - three.posx)<20 && abs(DefenderY-three.posy )<20 ||
abs(DefenderX - four.posx)<20 && abs(DefenderY-four.posy )<20
)//are they close together?
{
print ("GAMEOVER!");
}
float bulletY = DefenderY;
float bulletX= DefenderX;
rect(bulletX, bulletY, 8, 8);
text("score: ", countA, 20, 80);
if (keyPressed && key==CODED && key == 's')// if the space bar is pressed
{
dropping = true;
print("its working");
if (bulletY<=400)
bulletY= bulletY + 1;
}
if(dropping == true){
}
if(bulletY>=400){dropping = false;
bulletY=DefenderY;
bulletX=DefenderX +30;}
int randomattack, randomattack1, randomattack2, randomattack3;
randomattack = (int)Math.floor(Math.random()*(two.max-two.min+1)+two.min);
ellipse(one.posx,one.posy, 10,10); //draw ball at current position : x, y fixed at 125!
one.posy = one.posy - 1;
if (abs(one.posy -1 )<1 )
{one.posy = one.posy+ 400;
one.posx = randomattack;}
randomattack1 = (int)Math.floor(Math.random()*(two.max-two.min+1)+two.min);
ellipse(two.posx,two.posy, 10,10); //draw ball at current position : x, y fixed at 125!
two.posy = two.posy - 1;
if (abs(two.posy -1 )<1 )
{two.posy = two.posy+ 400;
two.posx = randomattack1;}
randomattack2 = (int)Math.floor(Math.random()*(two.max-two.min+1)+two.min);
ellipse(three.posx,three.posy, 10,10); //draw ball at current position : x, y fixed at 125!
three.posy = three.posy - 1;
if (abs(three.posy -1 )<1 )
{three.posy = three.posy+ 400;
three.posx = randomattack2;}
randomattack3 = (int)Math.floor(Math.random()*(one.max-one.min+1)+one.min);
ellipse(four.posx,four.posy, 10,10); //draw ball at current position : x, y fixed at 125!
four.posy = four.posy - 1;
if (abs(four.posy -1 )<1 )
{four.posy = four.posy+ 400;
four.posx = randomattack3;}
}void keyPressed()
{
if (key==CODED)
{
if (keyCode == LEFT)
{ DefenderX = DefenderX - 5; }
if (keyCode == RIGHT)
{ DefenderX = DefenderX + 5; }
}
}
This is the part of your code that draws the bullet:
float bulletY = DefenderY;
float bulletX = DefenderX;
rect(bulletX, bulletY, 8, 8);
You set the bullet position to Defender position and then immediately draw it.
You have some code later on that adjusts the bullet position, but it won't have any effect because you've already drawn the bullet on screen at the original position.
Also note that the draw function runs every frame, so you probably don't want to be resetting the bullet position each frame like that or it will be difficult to get it to move anywhere. Declare the variables for bullet position outside of draw and only reset them when the bullet is initially fired.
I am making a game in Java (No Libraries).
It's a 2D top-down game where the player can walk and is faced towards the mouse cursor.
public Player(int x, int y, int health, int tileId) {
super(x, y, health);
tile = new Tile(tileId, false);
mouseInput = new MouseHandler(screen);
}
public void tick() { // Executed by game tick.
// x = playerX and y = playerY
int cursorX = mouseInput.getMousePos()[0];
int cursorY = mouseInput.getMousePos()[1];
float X = cursorX - x;
float Y = cursorY - y;
rotation = Math.atan2(Y, X);
}
It looks good as long the player is at (0,0)
If the player moves and the mouse coordinates become negative it begins to show strange behaviour (Look at video below)
Youtube: https://www.youtube.com/watch?v=M6ZHCrWvt3Y
The rotation of the sprite is done in another class 'Screen.java'
By using:
if (rotation < 360)
rotation++
else
rotation = 0
I verified that the rotation is working correctly.
EDIT:
public BufferedImage rotate(BufferedImage img, double degree) {
AffineTransform tx = new AffineTransform();
tx.rotate(degree, 4, 4);
AffineTransformOp op = new AffineTransformOp(tx,AffineTransformOp.TYPE_BILINEAR);
BufferedImage image = op.filter(img,null);
return image;
}
Okay i fixed it.
The problem was the game scale i am making an 2d game and set the width, height and the scale.
But i didn't divide the mouseX and mouseY by the scale.
public void mouseMoved(MouseEvent e) {
mouseX = e.getX() / game.getScale();
mouseY = e.getY() / game.getScale();
}
I found the problem by accident when messing with the gamescale.
I am using this method with AndEngine to add a sprite to the screen and make it move across the screen.
private void addFace() {
Random rand = new Random();
float x = (int) mCamera.getHeight() - mBallTextureRegion.getHeight();
float minY = mBallTextureRegion.getHeight();
float maxY = (int)(mCamera.getWidth() + mBallTextureRegion.getWidth());
float rangeY = maxY - minY;
float y = rand.nextInt((int)rangeY) + minY;
this.mFaceCount++;
Log.e("Faces: ", "Face" + this.mFaceCount);
Sprite face = null;
Body body = null;
face = new Sprite(x, y, this.mBallTextureRegion.clone());
body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, FIXTURE_DEF);
this.mScene.attachChild(face);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face, body, true, true));
int minDuration = 2;
int maxDuration = 4;
int rangeDuration = maxDuration - minDuration;
int actualDuration = rand.nextInt(rangeDuration) + minDuration;
MoveXModifier mod = new MoveXModifier(actualDuration, face.getX(), - face.getWidth());
face.registerEntityModifier(mod);
}
What i would like to do is, instead of the Random position being selected and the sprite being added to the left side of the Scene, i would like for it to be added to the Top and fall down.
I basically want to flip the direction,
I just cant figure out how. Everything i tried was no luck.
Any ideas or suggestions?
While I don't know much about Andengine, I suspect you would want to change these lines:
float x = (int) mCamera.getHeight() - mBallTextureRegion.getHeight();
float y = rand.nextInt((int)rangeY) + minY;
MoveXModifier mod = new MoveXModifier(actualDuration, face.getX(), - face.getWidth());
Flip the x and y statements, but set y to -mBallTextureRegion.getHeight() if you want it to appear outside the screen.
For the MoveXModifier, I would guess there is a corresponding MoveYModifier (use face.getY() and -face.getHeight() respectively)
I have another question, this is also extra credit and not homework. This time I need to create a border with out using java2d. The instructions are...
Write a method called drawRectangleBorder having six parameters which does not use the graphics package. It draws a rectangular border starting at the x and y coordinates given as the first two parameters, having a width and height given by the third and fourth parameters, the width of the border given by the fifth parameter in the color given by the sixth parameter. The parameter list is: x, y, width, height, borderWidth, color
I used a previous method I made to create a border around the outside of a picture but the best I can make it do now is a couple scattered boxes. The most recent version will not show anything
public void drawRectangleBorder(
int x, int y, int width, int height, int border, Color newColor) {
int startX = 0;
int startY = 0;
// top and bottom
for (startX = x; x < width; x++) {
for (startY = y; y < border; y++) {
// top pixel
this.getPixel(startX, startY).setColor(newColor);
// bottom pixel
this.getPixel(startX + width, startY + height).setColor(newColor);
} // for-y
} // for-x
// left and right
for (startX = x; x < border; x++) {
for (startY = y; y < height; y++) {
// left pixel
this.getPixel(startX, startY).setColor(newColor);
// right pixel
this.getPixel(startX + width, StartY + height).setColor(newColor);
} // for-y
} // for-x
return;
} // end drawRectangleBorder
Again I thank you for any input.
You can alter the pixels in a java.awt.BufferedImage as shown here.
I might be too sleepy but I think your forgetting to set the pixel back into this (whatever this is ^^)
I'm guessing this.getPixel sends your back a copy so you might want to do something like
Pixel p = this.getPixel( startX, startY );
p.setColor(newColor);
this.setPixel(startX, startY, p);