<commit_before>package javagames.render;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import javagames.util.FrameRate;
import javagames.util.KeyboardInput;
import javagames.util.Matrix3x3f;
import javagames.util.RelativeMouseInput;
import javagames.util.Vector2f;

public class GameApp extends JFrame implements Runnable {

	private static final long serialVersionUID = -5612855817410359454L;
	
	private static final int SCREEN_W = 640;
	private static final int SCREEN_H = 480;
	
	private FrameRate frameRate;
	private BufferStrategy bufferStrategy;
	private volatile boolean running;
	private Thread gameThread;
	private RelativeMouseInput mouse;
	private KeyboardInput keyboard;
	
	private float earthRot, earthDelta;
	private float moonRot, moonDelta;
	
	private boolean showStars;
	private int[] stars;
	private Random rand = new Random();
	
	public GameApp() {
	}
	
	protected void createAndShowGUI() {
		Canvas canvas = new Canvas();
		canvas.setSize(SCREEN_W, SCREEN_H);
		canvas.setBackground(Color.BLACK);
		canvas.setIgnoreRepaint(true);
		getContentPane().add(canvas);
		
		setTitle("Game Application");
		setIgnoreRepaint(true);
		pack();
		
		// Add key listeners
		keyboard = new KeyboardInput();
		canvas.addKeyListener(keyboard);
		
		// Add mouse listeners
		mouse = new RelativeMouseInput(canvas);
		canvas.addMouseListener(mouse);
		canvas.addMouseMotionListener(mouse);
		canvas.addMouseWheelListener(mouse);
		
		setVisible(true);
		canvas.createBufferStrategy(2);
		bufferStrategy = canvas.getBufferStrategy();
		canvas.requestFocus();
		
		gameThread = new Thread(this);
		gameThread.start();
	}
	
	@Override
	public void run() {
		running = true;
		initialize();
		while (running) {
			gameLoop();
		}
	}
	
	private void gameLoop() {
		processInput();
		renderFrame();
		sleep(10L);
	}
	
	private void renderFrame() {
		do {
			do {
				Graphics g = null;
				try {
					g = bufferStrategy.getDrawGraphics();
					g.clearRect(0, 0, getWidth(), getHeight());
					render(g);
				} finally {
					if (g != null) {
						g.dispose();
					}
				}
			} while (bufferStrategy.contentsRestored());
			bufferStrategy.show();
		} while (bufferStrategy.contentsLost());
	}
	
	private void sleep(long sleep) {
		try {
			Thread.sleep(sleep);
		} catch (InterruptedException e) {
			// Do nothing.
		}
	}
	
	private void initialize() {
		frameRate = new FrameRate();
		frameRate.initialize();
		
		earthDelta = (float)Math.toRadians(0.5);
		moonDelta = (float)Math.toRadians(2.5);
		
		showStars = true;
		stars = new int[1000];
		
		for (int i = 0; i < stars.length - 1; i += 2) {
			stars[i] = rand.nextInt(SCREEN_W);
			stars[i+1] = rand.nextInt(SCREEN_H);
		}
	}
	
	private void processInput() {
		keyboard.poll();
		mouse.poll();
		
		if (keyboard.keyDownOnce(KeyEvent.VK_SPACE)) {
			showStars = !showStars;
		}
	}
	private void render(Graphics g) {
		frameRate.calculate();
		
		g.setFont(new Font("Courier New", Font.PLAIN, 12));
		g.setColor(Color.GREEN);
		g.drawString(frameRate.getFrameRate(), 20, 20);
		g.drawString("Press [SPACE] to toggle stars", 20, 35);
		
		if (showStars) {
			g.setColor(Color.WHITE);
			for (int i = 0; i < stars.length - 1; i++) {
				g.fillRect(stars[i], stars[i+1], 1, 1);
			}
		}
		
		// Draw the sun
		Matrix3x3f sunMatrix = Matrix3x3f.identity();
		sunMatrix = sunMatrix.mul(Matrix3x3f.translate(SCREEN_W / 2, SCREEN_H / 2));
		
		Vector2f sun = sunMatrix.mul(new Vector2f());
		g.setColor(Color.YELLOW);
		g.fillOval((int)sun.x - 50, (int)sun.y - 50, 100, 100);
		
		// Draw earth's orbit
		g.setColor(Color.WHITE);
		g.drawOval((int)sun.x - SCREEN_W / 4, (int)sun.y - SCREEN_W / 4, SCREEN_W / 2, SCREEN_W / 2);
		
		// Draw the earth
		Matrix3x3f earthMatrix = Matrix3x3f.translate(SCREEN_W / 4, 0);
		earthMatrix = earthMatrix.mul(Matrix3x3f.rotate(earthRot));
		earthMatrix = earthMatrix.mul(sunMatrix);
		
		earthRot += earthDelta;
		
		Vector2f earth = earthMatrix.mul(new Vector2f());
		g.setColor(Color.BLUE);
		g.fillOval((int)earth.x - 10, (int)earth.y - 10, 20, 20);
		
		// Draw the moon
		Matrix3x3f moonMatrix = Matrix3x3f.translate(30, 0);
		moonMatrix = moonMatrix.mul(Matrix3x3f.rotate(moonRot));
		moonMatrix = moonMatrix.mul(earthMatrix);
		moonRot += moonDelta;
		
		Vector2f moon = moonMatrix.mul(new Vector2f());
		g.setColor(Color.LIGHT_GRAY);
		g.fillOval((int)moon.x - 5, (int)moon.y - 5, 10, 10);
	}
	
	protected void onWindowClosing() {
		try {
			running = false;
			gameThread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.exit(0);
	}
	
	public static void main(String[] args) {<commit_msg>Chapter 4: Calculation of time delta to keep movement constant<commit_after>package javagames.render;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import javagames.util.FrameRate;
import javagames.util.KeyboardInput;
import javagames.util.Matrix3x3f;
import javagames.util.RelativeMouseInput;
import javagames.util.Vector2f;

public class GameApp extends JFrame implements Runnable {

	private static final long serialVersionUID = -5612855817410359454L;
	
	private static final int SCREEN_W = 480;
	private static final int SCREEN_H = 480;
	
	private FrameRate frameRate;
	private BufferStrategy bufferStrategy;
	private volatile boolean running;
	private Thread gameThread;
	private RelativeMouseInput mouse;
	private KeyboardInput keyboard;
	private Canvas canvas;
	
	private float angle;
	private float step;
	private long sleep;
	
	public GameApp() {
	}
	
	protected void createAndShowGUI() {
		canvas = new Canvas();
		canvas.setSize(SCREEN_W, SCREEN_H);
		canvas.setBackground(Color.WHITE);
		canvas.setIgnoreRepaint(true);
		getContentPane().add(canvas);
		
		setTitle("Game Application");
		setIgnoreRepaint(true);
		pack();
		
		// Add key listeners
		keyboard = new KeyboardInput();
		canvas.addKeyListener(keyboard);
		
		// Add mouse listeners
		mouse = new RelativeMouseInput(canvas);
		canvas.addMouseListener(mouse);
		canvas.addMouseMotionListener(mouse);
		canvas.addMouseWheelListener(mouse);
		
		setVisible(true);
		canvas.createBufferStrategy(2);
		bufferStrategy = canvas.getBufferStrategy();
		canvas.requestFocus();
		
		gameThread = new Thread(this);
		gameThread.start();
	}
	
	@Override
	public void run() {
		running = true;
		initialize();
		long currentTime = System.nanoTime();
		long lastTime = currentTime;
		double nsPerFrame;
		while (running) {
			currentTime = System.nanoTime();
			nsPerFrame = currentTime - lastTime;
			gameLoop(nsPerFrame / 1.0E9);
			lastTime = currentTime;
		}
	}
	
	private void gameLoop(double timeDelta) {
		processInput(timeDelta);
		updateObjects(timeDelta);
		renderFrame();
		sleep(sleep);
	}
	
	private void renderFrame() {
		do {
			do {
				Graphics g = null;
				try {
					g = bufferStrategy.getDrawGraphics();
					g.clearRect(0, 0, getWidth(), getHeight());
					render(g);
				} finally {
					if (g != null) {
						g.dispose();
					}
				}
			} while (bufferStrategy.contentsRestored());
			bufferStrategy.show();
		} while (bufferStrategy.contentsLost());
	}
	
	private void sleep(long sleep) {
		try {
			Thread.sleep(sleep);
		} catch (InterruptedException e) {
			// Do nothing.
		}
	}
	
	private void initialize() {
		frameRate = new FrameRate();
		frameRate.initialize();
		
		angle = 0.0f;
		step = (float)Math.PI / 2.0f;
	}
	
	private void processInput(double timeDelta) {
		keyboard.poll();
		mouse.poll();
		
		if (keyboard.keyDownOnce(KeyEvent.VK_UP)) {
			sleep += 10;
		}
		
		if (keyboard.keyDownOnce(KeyEvent.VK_DOWN)) {
			sleep -= 10;
		}
		
		if (sleep > 1000) {
			sleep = 1000;
		}
		
		if (sleep < 0) {
			sleep = 0;
		}
	}
	
	private void updateObjects(double timeDelta) {
		angle += step * timeDelta;
		if (angle > 2 * Math.PI) {
			angle -= 2 * Math.PI;
		}
	}

	private void render(Graphics g) {
		frameRate.calculate();
		
		g.setFont(new Font("Courier New", Font.PLAIN, 12));
		g.setColor(Color.BLACK);
		g.drawString(frameRate.getFrameRate(), 20, 20);
		g.drawString("Up arrow increases sleep time", 20, 35);
		g.drawString("Down arrow decreases sleep time", 20, 50);
		g.drawString("Sleep time (ms): " + sleep, 20, 65);
		
		int x = canvas.getWidth() / 4;
		int y = canvas.getHeight() / 4;
		int w = canvas.getWidth() / 2;
		int h = canvas.getHeight() / 2;
		g.drawOval(x, y, w, h);
		
		float radiusWidth = w / 2;
		float radiusHeight = h / 2;
		int rx = (int)(radiusWidth * Math.cos(angle));
		int ry = (int)(radiusHeight * Math.sin(angle));
		
		int cx = (int)(rx + w);
		int cy = (int)(ry + h);
		
		// Draw clock hand
		g.drawLine(w, h, cx, cy);
		// and the dot at the ond of the hand
		g.drawRect(cx - 2, cy - 2, 4, 4);
	}
	
	protected void onWindowClosing() {
		try {
			running = false;
			gameThread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.exit(0);
	}
	
	public static void main(String[] args) {
{'fraction_non_alphanumeric': 0.12924088210347753, 'fraction_numerical': 0.021628498727735368, 'mean_word_length': 3.6883697813121272, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '799705', 'n_tokens_mistral': 3822, 'n_tokens_neox': 3191, 'n_words': 748}