Noob Questions From Nickropheliac: Adding ScreenShake Every Collision

So for my first game I have this little pong game, that I started at 3 am. I woke up this morning and realized that I understood most of what I had did the previous night, and what I currently had was somewhat boring. I thought adding screenshake, and increasing speed of the paddle and the ball every interval of 5 would also be very interesting.

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JPanel;
import javax.swing.Timer;

public class PongPanel extends JPanel implements ActionListener, KeyListener{

    private boolean upPressed = false;
    private boolean downPressed = false;
    private boolean wPressed = false;
    private boolean sPressed = false;

    private int ballX = 250;
    private int ballY = 250;
    private int diameter = 20;
    private int ballDeltaX = -3;
    private int ballDeltaY = 3;

    private int playerOneX = 25;
    private int playerOneY = 250;
    private int playerOneWidth = 20;
    private int playerOneHeight = 60;

    private int playerTwoX = 455;
    private int playerTwoY = 250;
    private int playerTwoWidth = 20;
    private int playerTwoHeight = 60;

    private int paddleSpeed = 5;



    public PongPanel(){
        setBackground(Color.BLACK);

      
        setFocusable(true);
        addKeyListener(this);

        Timer timer = new Timer(1000/60, this);
        timer.start();
    }


    public void actionPerformed(ActionEvent e){
        step();
    }

    public void step(){

       
        if (upPressed) {
            if (playerOneY-paddleSpeed > 0) {
                playerOneY -= paddleSpeed;
            }
        }
        if (downPressed) {
            if (playerOneY + paddleSpeed + playerOneHeight < getHeight()) {
                playerOneY += paddleSpeed;
            }
        }

        if (wPressed) {
            if (playerTwoY-paddleSpeed > 0) {
                playerTwoY -= paddleSpeed;
            }
        }
        if (sPressed) {
            if (playerTwoY + paddleSpeed + playerTwoHeight < getHeight()) {
                playerTwoY += paddleSpeed;
            }
        }



        
        int nextBallLeft = ballX + ballDeltaX;
        int nextBallRight = ballX + diameter + ballDeltaX;
        int nextBallTop = ballY + ballDeltaY;
        int nextBallBottom = ballY + diameter + ballDeltaY;

        int playerOneRight = playerOneX + playerOneWidth;
        int playerOneTop = playerOneY;
        int playerOneBottom = playerOneY + playerOneHeight;

        float playerTwoLeft = playerTwoX;
        float playerTwoTop = playerTwoY;
        float playerTwoBottom = playerTwoY + playerTwoHeight;


        
        if (nextBallTop < 0 || nextBallBottom > getHeight()) {
            ballDeltaY *= -1;
        }


        if (nextBallLeft < playerOneRight) { 
  
            if (nextBallTop > playerOneBottom || nextBallBottom < playerOneTop) {

                System.out.println("Point, Player Two.");

                ballX = 250;
                ballY = 250;
            }
            else {
                ballDeltaX *= -1;
            }
        }

      
        if (nextBallRight > playerTwoLeft) {
            
            if (nextBallTop > playerTwoBottom || nextBallBottom < playerTwoTop) {

                System.out.println("Point, Player Two.");

                ballX = 250;
                ballY = 250;
            }
            else {
                ballDeltaX *= -1;
            }
        }

        
        ballX += ballDeltaX;
        ballY += ballDeltaY;

        repaint();
    }

    public void paintComponent(Graphics g){

        super.paintComponent(g);
        g.setColor(Color.WHITE);

        g.fillRoundRect(ballX, ballY, 25, 25, 5, 25);

        g.fillRoundRect(playerOneX, playerOneY, playerOneWidth, playerOneHeight, 50, 5);
        g.fillRoundRect(playerTwoX, playerTwoY, playerTwoWidth, playerTwoHeight,50, 5);
    }



    public void keyTyped(KeyEvent e) {}



    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            upPressed = true;
        }
        else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            downPressed = true;
        }
        else if (e.getKeyCode() == KeyEvent.VK_W) {
            wPressed = true;
        }
        else if (e.getKeyCode() == KeyEvent.VK_S) {
            sPressed = true;
        }
    }


    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            upPressed = false;
        }
        else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            downPressed = false;
        }
        else if (e.getKeyCode() == KeyEvent.VK_W) {
            wPressed = false;
        }
        else if (e.getKeyCode() == KeyEvent.VK_S) {
            sPressed = false;
        }
    }


So like I said I wanted to add screenshake. It’s really good for “game feel”. There is also a great talk on game feel from the game designer from Vlambeer, Jan Willem Nijman https://www.youtube.com/watch?v=AJdEqssNZ-U. It shows the progressive improvement of a simple game just using simple or small changes. Such as screenshake. Please help me understand how to implement this.

Also I wish to make a rally integer for every time the ball collides with the paddle. Every 5 times I wish for it to increase the speed of the ball and paddle, which is pretty easy to do. However, what would I set this integer equal to? ??? ???

Well, screenshake is absolutely one of those things we could tell you how to implement, but like mentioned in your other thread, this is one of those things which help you more if you try to figure them out yourself instead, because it helps you to get more into the process of actually solving problems.

EDIT: Also, this will probably be your first game, so dont try to take too big steps. Game design is maybe the most important part in creating a game, but you are still learning from the technical standpoint right now, and thats probably what you should focus on for now.

I agree with everything Drenius said.

Think about what you want to do: what exactly is screenshake? Can you describe it in very specific details that even the dumbest person on earth could understand? When you have that description written out, you’ll have an algorithm that you can start thinking about implementing.

Continuously asking “how do I do this” type questions won’t get you very far. You have to think about the problem, break it down into smaller steps, and then start working on one of those small steps. Create a little test program separate from your entire project that tries a few things out. Can you create a program that displays a single square that shakes? Can you make it so it only shakes when you press a button? When you have that working (separate from your Pong project), then you can think about implementing it into the larger solution.

And if you get confused on a specific step, then you can post an MCVE that shows us exactly what you’ve tried and where you’re stuck, and you’ll get much more help than if you keep asking “how do I do this” type questions.

I know the screen shake you mean , a large knock to the offset then moving back and forth for a bit and reseting . Think of utilizing an offset variable within your render functions so you store all the x positions so do something with them and play around with the shaking.

Assuming you’re using Java2D, just use a function like [icode]g.translate(x, y)[/icode] for this. The easiest way to create a screenshake ‘effect’ is by generating a couple random values and translating the viewport to wherever those values point to.

To do this, use Java’s [icode]Random[/icode] class. It’s really useful for doing small things like what you’re trying to do right now.

  • Jev

Thanks, I’ll tell you if it works :smiley: