I'm currently learning Java through Stanford's Programming Methodology (2008) course. I'm trying to create the game Breakout and am trying to currently animate the paddle, which is a GRect type object. Here's my code:
// moves paddle via keyboard
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_RIGHT && paddle.getX() < getWidth() - paddle.getWidth()) {
paddle.move(5, 0);
}
if (key == KeyEvent.VK_LEFT && paddle.getX() > 0) {
paddle.move(-5, 0);
}
}
//moves paddle via mouse
public void mouseMoved(MouseEvent e) {
while (e.getX() > paddle.getX() + PADDLE_WIDTH/2 && paddle.getX() < getWidth() - PADDLE_WIDTH) {
paddle.move(1, 0);
}
while (e.getX() < paddle.getX() + PADDLE_WIDTH/2 && paddle.getX() > 0) {
paddle.move(-1, 0);
}
The problem is, if I move the paddle with mouse, it follows just fine, it's much smoother than when I try to move it with keyboard. Changing the values in move() method only changes the speed at which the paddle moves.
I've tried googling and one of the things people do is to gradually increase and decrease the speed at which the paddle moves, but I'm not sure how to implement that correctly through this library. Here's my attempt:
private double acceleration(double finalSpeed) {
if (finalSpeed > initialSpeed) {
initialSpeed += delta;
} else if (finalSpeed < initialSpeed) {
initialSpeed -= delta;
}
return initialSpeed;
}
private double initialSpeed = 0;
private double delta = 0.5;
After this I just set the paddle.move(acceleration(5),0) instead of paddle.move (5,0). And I've also added the KeyReleased method that sets the speed to the initial value:
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_RIGHT || key == KeyEvent.VK_LEFT) {
initialSpeed = 0;
}
However, the movement of the paddle when I switch between left and right arrow keys is not responsive. It has about 0.5 sec delay to start moving the other direction, I've spend whole day trying to figure out the solution but to no avail. Please give me any tips, thanks!
It seems that there's some problem with the threads (which I don't fully understand). Doing this helped:
Instead of moving the paddle directly with listeners, I created two booleans: left_key_downand right_key_down and set them to true if corresponding key was pressed. After that I moved the paddle using: if (left_key_down) move (-5,0) And similarly with right motion. This resulted in smooth motion.
Related
The following code I wrote does what I want, a touch on the left or right side of the screen to move the sprite left or right and stop at the edge of the phone screen. The issue I'm having is when you do a fast motion of touching the right side of the screen, letting go while using another finger to touch the left side of the screen to change direction will yield a result of the sprite still moving to the right side of the screen despite you wanting to move left. In order to fix this, you need to let go completely for at least 0.5sec then press the other direction to start moving in that direction, which I don't want to have to live with. If anyone has any tips/help for this, please let me know!
MAIN ACTIVITY CLASS METHOD:
public boolean onTouchEvent(MotionEvent event){
int x = (int)event.getX();
switch(event.getAction()) {
case (MotionEvent.ACTION_DOWN):
CharacterSprite.touchedX = x;
break;
case (MotionEvent.ACTION_UP):
CharacterSprite.touchedX = 0;
break;
}
return super.onTouchEvent(event);
}
CHARACTERSPRITE CLASS METHOD:
public void update() {
if (touchedX != 0) {
if (touchedX < screenWidth / 2) {
if (!(xVelocity < 0)) {
xVelocity = xVelocity * -1;
}
if (!(x > 0)) {
touchedX = 0;
return;
}
x += xVelocity;
}
if (touchedX > screenWidth / 2) {
if (!(xVelocity > 0)) {
xVelocity = xVelocity * -1;
}
if (!(x < screenWidth - image.getWidth())) {
touchedX = 0;
return;
}
x += xVelocity;
}
}
}
The way you handling MotionEvent will not work for multitouch events. Each finger (action pointer) data stored as an array and you need to handle each entry separately. Here is the lesson on handling multitouch events:
https://developer.android.com/training/gestures/multi
I'm in grade 12 right now and I working on a Pacman game for my computer science class.
What I so far have is a file called Play.java that runs the actual game. I have an init method that initializes the sprite sheets, images, and animations. Then I have a render method that draws the maze and Pacman on the screen. Last, I have an update method that pretty much updates whats on the screen.
This is what's inside the update function:
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
pacman.update(delta);
Input input = gc.getInput();
Color walls;
if(input.isKeyDown(Input.KEY_UP)) {
walls = maze.getColor((int) pacmanPosX, (int) pacmanPosY - 2);
if (walls.getRed() == 0 && walls.getGreen() == 0 && walls.getBlue() == 0) {
pacman = pacmanAnimation[2];
pacmanPosY -= delta * .1f;
}
} else if(input.isKeyDown(Input.KEY_DOWN)) {
walls = maze.getColor((int) pacmanPosX, (int) pacmanPosY + 20);
if (walls.getRed() == 0 && walls.getGreen() == 0 && walls.getBlue() == 0) {
pacman = pacmanAnimation[3];
pacmanPosY += delta * .1f;
}
} else if(input.isKeyDown(Input.KEY_LEFT)) {
walls = maze.getColor((int) pacmanPosX - 2, (int) pacmanPosY);
if (walls.getRed() == 0 && walls.getGreen() == 0 && walls.getBlue() == 0) {
pacman = pacmanAnimation[0];
pacmanPosX -= delta * .1f;
}
} else if(input.isKeyDown(Input.KEY_RIGHT)) {
walls = maze.getColor((int) pacmanPosX + 20, (int) pacmanPosY);
if (walls.getRed() == 0 && walls.getGreen() == 0 && walls.getBlue() == 0) {
pacman = pacmanAnimation[1];
pacmanPosX += delta * .1f;
}
}
}
So basically I allow the user to move Pacman around the screen and I check the pixel color of the future position that Pacman may land. If the future position is not black, Pacman may not continue moving in that direction. This concept works for the most part, except Pacman can move through a rectangle if it starts off at the top left/right corner.
Here's an image of what I'm talking about:
I circled in red the areas where Pacman is able to move when it shouldn't.
How do I fix this issue? I don't want Pacman to be on top of any blue rectangles. If you want me to add more code, I can but I think the update method is enough for now. Just trying to create an MCVE.
Also, I'm using Slick2D and LWJGL for this game.
I am really new to programming. For my class, I am making a game and I would like to add a seconds player to the game. At the moment, there are black circles that appear randomly in the game and keep growing. You are a circle and you need to avoid the circles for as long as possible. Once you intersect with one the game ends. This circle is controlled with the arrow keys. However I would like to add a new circle with the keys WASD. This is my code so far. But when the game starts I can see the circle but I cannot move it.
The main part of the code I am worried about is ProcessUserInput2 because that is the code that controls WASD. I have not pasted in my entire code. Any help would be much appreciated
void draw()
{
//Call functions
if (gameState == 0)//Start Screen
{
ProccessUserInput_Start(); //this function is in a separate tab. It processes what the player inputs into the computer, and then translates it into commands
Render_Start();
savedTime = millis();
}
if (gameState == 1)//Game Playing Screen
{
ProcessUserInput1(); //this is for the arrow keys
ProcessUserInput2(); //this is for WASD
Render();
totalTime = 40000; //Timer (in millis)
for (growingEllipse e:ellipses)
{
e.ellipseGrow();
e.rendering();
}
void ProcessUserInput1()
//Move circle Left, Right, Up or Down using arrow keys
{
if (keyPressed)
{
if (keyCode == LEFT)//Move Left
{
x1 = x1 - 2;
}
if (keyCode == RIGHT)//Move Right
{
x1 = x1 + 2;
}
if (keyCode == UP)//Move Up
{
y1 = y1 - 2;
}
if (keyCode == DOWN)//Move Down
{
y1 = y1 + 2;
}
}
}
void ProcessUserInput2()
//Move circle Left, Right, Up or Down using arrow keys
{
if (keyPressed)
{
if (keyCode == 'A')//Move Left
{
x2 = x2 - 2;
}
if (keyCode == 'D')//Move Right
{
x2 = x2 + 2;
}
if (keyCode == 'W')//Move Up
{
y2 = y2 - 2;
}
if (keyCode == 'S')//Move Down
{
y2 = y2 + 2;
}
}
}
void Render()
{
background(255);
fill(255, 228, 196);
ellipse (x1, y1, r1, r1);
ellipse (x2, y2, r1, r1);
//draw circle for player
}
If possible, could any really good programmers give me their email so that I can ask them questions? I still need to add in a few more items such as inheritance and function overloading. I used the Processing application for this.
You're using the keyCode variable, which only works with things like the arrow keys that don't have associated characters.
Instead, you might want to use the key variable, which is a char and contains the character typed.
More info here: http://staticvoidgames.com/tutorials/intermediateConcepts/keyboardInput
Edit: Also, as Jordi said, you're only catching upper-case letters. And please don't ask for email, as that defeats the whole point of public sites like this.
im quite new to java. I am trying to make it so that i can control a ball with the arrow keys and then if you collide with another ball, it will print a line in the console saying "you lost" or somthing.
I have done the moving, but i am struggling a bit with how i can get the 2 balls to collide. so far i have tried this (i think i put a rectangle around the ball, but i don't know really!):
public void collision() {
Rectangle rectP = new Rectangle(player.x, player.y, player.WIDTH, player.HEIGHT);
Rectangle rectE = new Rectangle(Enemy.ex, Enemy.ey, Enemy.WIDTH, Enemy.HEIGHT);
if(rectP.intersects(rectE))
{
System.out.println("game over");
}
}
Could someone help me out and explain what i have done wrong.
ps. please don't just give me the code, i do want to try and learn!!!.
thanks.
public void actionPerformed(ActionEvent e) {
repaint();
x += velx;
y += vely;
}
public void up() {
vely = -1.5;
velx = 0;
}
public void down() {
vely = 1.5;
velx = 0;
}
public void left() {
vely = 0;
velx = -1.5;
}
public void right() {
vely = 0;
velx = 1.5;
}
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP) {
up();
}
if (code == KeyEvent.VK_DOWN) {
down();
}
if (code == KeyEvent.VK_LEFT) {
left();
}
if (code == KeyEvent.VK_RIGHT) {
right();
}
}
If you have coords X and Y of the two ball centers and you know balls radiuses - this should be a simple task.
Just calculate the distance between centers of the balls and compare it with sum of balls radiuses.
You asked to skip formulas so that's it :)
PS What looks strange in your code is that player is lowercased but Enemy is capitalized.. is it a class or an object?
Well, I don't think that what is wrong is the collision detection. I think that what is wrong is that what the computer think that the objects are somewhere else then where they actually are. Like one time when I was trying to make a brickbreaker paddle, I was having problems with collision detection when really the program thought that the paddle was on the opposite side! What you should do is that you should draw the positions of the rectangle onto the game. This way, you can see where the computer thinks the objects are. Maybe they are totally off?
In my game, the player navigates a maze. I can't figure out how to do proper collision detection with the walls. It is easy to do collision detection for staying in a certain area:
if (x > rightWallX - playerWidth) x = rightWallX - playerWidth;
if (x < leftWallX) x = leftWallX;
//...
But how would I do collision detection for many walls?
I can do plain collision detection without correction (like if (intersecting) return true;), but I can't correct this correctly. If I just store the old x and y and reset them, then
The object never actually touches the wall
If the object can go up but is blocked to the right, it won't go up, it will just not move.
How is collision detection in a maze done?
The easiest way, once you have solved collision detection, to fix the collision is to move the actor to the closest valid position to where the actor would be were it not for the object it collides with. This assumes no inertia, but it is sufficient for maze-like games or top-down map-crawling games.
If you want to simplify your calculations further, you can limit yourself to detecting if changing the actor's x or y coordinate would be better. If your actor has an axis-aligned rectangular hit-box and all obstacles are axis-aligned rectangular as well (the simplest case), this assumption is indeed correct. However, the results might not be satisfactory in some other cases (potential artifact: speed boost from gliding diagonal walls - not the case in most maze games).
Keep in mind multiple collisions could happen concurrently (pushing against two walls). If there are no sharp angles between two walls that an actor could both intersect (say, if all your obstacles are axis aligned and sufficiently spaced), fixing each collision in turn will suffice - just don't stop after the first collision.
You can use Rectangle.intersects() method:
public Rectangle Player(){
return new Rectangle(PlayerX,PlayerY,PlayerWidth,PlayerHeight);
//we do this for getting players x and y values every tick
}
if(Player().intersects(new Rectangle(0,0,100,50)))//if(player touching wall)
new Rectangle(0,0,100,50) is just an example you can change it.
Ok so i'm currently making a 2D top down view game and I'm not sure how you created your maze. However, in my game my Level is created from a Tile[][] tiles = new Tile[levelWidth][levelHeight]; array. The way i handled collision detection was by checking the surrounding tiles to see if they were solid.
This is my getTile method.
public Tile[][] getTile(int x, int y) {
if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) {
return new VoidTile();
} else {
return tiles[x][y];
}
}
In my Tile.java class i have a isSolid() method which returns whether the tile is solid or not. All of my tiles extend my Tile.java so they inherit this method and I override it in their constructor. As i said previously, I am not sure whether or not you use the same style of level implementation as i do. However, It is good practice to do it this way :)
Personally, I am not a big fan of using the .intersects() and .contains() methods for Sprite collision detection. I mainly use them for buttons and alike.
Ok so,
In my player.java class i have a checkBlockedDirection(int x, int y) method and it looks like this.
public void checkBlockedDirection(int x, int y) {
boolean u = map.getTile(x, y - 1).isSolid();
boolean d = map.getTile(x, y + 1).isSolid();
boolean l = map.getTile(x - 1, y).isSolid();
boolean r = map.getTile(x + 1, y).isSolid();
if (u) {
uBlocked = true;
System.out.println("up tile blocked");
} else {
uBlocked = false;
}
if (d) {
dBlocked = true;
System.out.println("down tile blocked");
} else {
dBlocked = false;
}
if (l) {
lBlocked = true;
System.out.println("left tile blocked");
} else {
lBlocked = false;
}
if (r) {
rBlocked = true;
System.out.println("right tile blocked");
} else {
rBlocked = false;
}
}
Then in my player update method i have this
public void tick() {
float dx = 0;
float dy = 0;
if (input.up.isPressed()) {
direction = 0;
} else if (input.down.isPressed()) {
direction = 2;
} else if (input.left.isPressed()) {
direction = 3;
} else if (input.right.isPressed()) {
direction = 1;
} else {
direction = 4; // standing
}
checkBlockedDirection((int)x, (int)y);
if (input.up.isPressed() && y > 0 && !uBlocked) {
dy += -speed;
} else if (input.down.isPressed() && y < map.getHeight() - 1 && !dBlocked) {
dy += speed;
} else if (input.left.isPressed() && x > 0 && !lBlocked) {
dx += -speed;
} else if (input.right.isPressed() && x < map.getWidth() - 1 && !rBlocked) {
dx += speed;
}
x += dx;
y += dy;
}
Basically it just checks whether or not the blocks up, down, left, or right are solid. If they are solid then it wont move and if they arent solid then you can move in the desired direction.
Not sure if this helps or not but it's just my take on this kind of grid collision detection :)
Hope this helps :)
Enjoy