Add files via upload

Milestone 1
This commit is contained in:
ahaas25
2022-01-04 15:53:01 -05:00
committed by GitHub
parent 570d553a29
commit aaf8d80665
15 changed files with 1801 additions and 0 deletions
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+478
View File
@@ -0,0 +1,478 @@
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.ArrayList;
public class gameWindow implements KeyListener, WindowListener, MouseListener {
private JFrame mainFrame;
private keyboard k = new keyboard();
private variables v = new variables();
private language l = new language();
mySurface s;
/**
* Initializes window and starts the graphics runner.
* Graphics runner runs @v.fps times a second.
*/
public gameWindow (int x, int y, String name) {
mainFrame = new JFrame(name);
mainFrame.setSize(x, y);
mainFrame.addKeyListener(this);
mainFrame.addWindowListener(this);
mainFrame.getContentPane().addMouseListener(this);
mainFrame.setFocusTraversalKeysEnabled(false);
s = new mySurface();
mainFrame.add(s);
mainFrame.setVisible(true);
graphicsRunner();
}
/**
* Redraws the window @v.fps times a second
*/
public void graphicsRunner() {
while(true) {
try {
Thread.sleep(1000/v.fps);
s.repaint();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
protected class mySurface extends JPanel {
double topBarHeight = 0.075;
double textHeight = 0.075;
int UIWidthArea = (int) (getWidth() * 0.8);
int UIHeight = (int) (getHeight() * 0.025);
int UITopBarHeightArea = (int) (getHeight() * topBarHeight);
int UIHeightArea = (int) (getHeight() * 0.9 * 0.5);
/**
* Main drawing method
* Calls UI drawing methods
*/
private void draw(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
drawUI(g);
drawKeyboard(g);
}
/**
* Draws the UI for typing teacher.
*/
private void drawUI(Graphics g) {
Font wordsFont = new Font("Arial", Font.PLAIN, 24);
double topBarHeight = 0.075;
double textHeight = 0.075;
int UIWidthArea = (int) (getWidth() * 0.8);
int UIHeight = (int) (getHeight() * 0.025);
int UITopBarHeightArea = (int) (getHeight() * topBarHeight);
int UIHeightArea = (int) (getHeight() * 0.9 * 0.5);
v.rOptions = new Rectangle(UIWidthArea, UIHeight, (int)
(getWidth() * 0.15), UITopBarHeightArea);
v.rScore = new Rectangle((int) (getWidth() * 0.05),
UIHeight, (int) (getWidth() * 0.15), UITopBarHeightArea);
v.rWPM = new Rectangle((int)
((UIWidthArea - getWidth() * 0.15)/2 + getWidth() * 0.1),
UIHeight, (int) (getWidth() * 0.15), UITopBarHeightArea);
v.rTopBar = new Rectangle((int) (getWidth() * 0.05),
UIHeight, (int) (getWidth() * 0.9), UITopBarHeightArea);
generateTestStrings(g, wordsFont, (int) (getWidth() * 0.8));
Rectangle lines[] = new Rectangle[v.drawLines];
v.WPMText = l.wpm + ": " + v.getWPM();
v.ScoreText = l.score + ": " + 0;
// Draw debug rectangles
if(v.debug) {
g.drawRect((int) v.rWPM.getX(), (int) v.rWPM.getY(),
(int) v.rWPM.getWidth(), (int) v.rWPM.getHeight());
g.drawRect((int) v.rScore.getX(), (int) v.rScore.getY(),
(int) v.rScore.getWidth(), (int) v.rScore.getHeight());
g.drawRect((int) v.rOptions.getX(), (int) v.rOptions.getY(),
(int) v.rOptions.getWidth(), (int) v.rOptions.getHeight());
}
g.drawRect((int) v.rTopBar.getX(), (int) v.rTopBar.getY(),
(int) v.rTopBar.getWidth(), (int) v.rTopBar.getHeight());
g.drawRect((int) (getWidth() * 0.05),
(int) (getHeight() * 0.025), (int) (getWidth() * 0.90),
UIHeightArea);
drawCenteredString(g, v.WPMText, v.rWPM, wordsFont);
drawCenteredString(g, v.ScoreText, v.rScore, wordsFont);
drawCenteredString(g, v.testWords + l.words, v.rOptions, wordsFont);
int textSizeY = (int) (textHeight * getHeight() * lines.length);
double topOfBarPadding = getHeight() * 0.025;
double topBarPadding = getHeight() * 0.025 + getHeight() * topBarHeight;
int yPadding = (int) ((getHeight() * 0.35) - textSizeY)/2;
generateTestStrings(g, wordsFont, UIWidthArea);
generateUserInputStrings();
int k = 0;
int middle = v.drawLines/2;
while(v.typedLines - middle - k > 0 && v.drawStrings.size() > k
+ v.drawLines)
k++;
for(int i = 0; i < lines.length; i++) {
lines[i] = new Rectangle((int) (getWidth() * 0.1),
(int) (topOfBarPadding/2 + topBarPadding + yPadding
+ textHeight * getHeight() * i),
(int) (getWidth() * 0.8), (int) (getHeight() * textHeight));
drawTypingPrompt(g, v.drawStrings.get(i+k),
v.userInputStrings.get(i+k), lines[i], wordsFont);
}
if(v.testOver) {
Rectangle rStatsWindow = new Rectangle((int) (getWidth() * 0.25),
UIHeight + UITopBarHeightArea * 2,
(int) (getWidth() * 0.5), (int) (UIHeightArea * 0.5));
Rectangle[] textLines = new Rectangle[4];
g.setColor(v.backgroundColor);
g.fillRect((int) rStatsWindow.getX(), (int) rStatsWindow.getY(),
(int) rStatsWindow.getWidth(), (int) rStatsWindow.getHeight());
g.setColor(v.textColor);
int counter = (int) (rStatsWindow.getY() / (textLines.length - 1));
for(int i = 0; i < textLines.length; i++) {
textLines[i] = new Rectangle((int) rStatsWindow.getX(),
(int) rStatsWindow.getY() + counter * i,
(int) rStatsWindow.getWidth(), counter);
}
drawCenteredString(g, l.testOver, textLines[0], wordsFont);
drawCenteredString(g, v.WPMText + l.raw, textLines[1], wordsFont);
drawCenteredString(g, l.accuracy + ": " + v.calculateAccuracy()
+ "%", textLines[2], wordsFont);
drawCenteredString(g, l.time + ": "
+ v.generateElapsedTimeString(), textLines[3], wordsFont);
}
}
/**
* Takes the user's input and converts it into strings the length of
* the test lines.
* Example:
* v.drawStrings: [window enter noon star, believe expect wash, chair city tube]
* User input: "window enter noon staa bnelieve expect was charity t tube"
* Output: [window enter noon staa, bnelieve expect was, charity t tube]
*/
private void generateUserInputStrings() {
//v.userString = v.getString();
v.userInputStrings.clear();
int position = 0;
v.typedLines = 0;
for(int i = 0; i < v.drawStrings.size(); i++) {
if(v.userString.length() - position <= v.drawStrings.get(i).length()) {// If userString is not as long as line
v.userInputStrings.add(v.userString.substring(position,
v.userString.length()));
i = v.drawStrings.size();
}
else { // If user completed string
v.userInputStrings.add(v.userString.substring(position,
position + v.drawStrings.get(i).length()));
position += v.drawStrings.get(i).length() + 1; // + 1 For space
v.typedLines++;
}
}
while(v.userInputStrings.size() < v.drawStrings.size()) {
v.userInputStrings.add("");
}
}
/**
* Calculates how many words can be displayed on a line and adds them
*/
private void generateTestStrings(Graphics g, Font font, int lineLength) {
String temp[] = v.getTestWords();
String toAdd = "";
FontMetrics metrics = g.getFontMetrics(font);
v.drawStrings.clear();
int length = 0;
for(String x : temp) {
int textLength = metrics.stringWidth(" " + x);
if(length + textLength < lineLength) {
length += textLength;
toAdd += x + " ";
}
else {
toAdd = v.backspace(toAdd);
v.drawStrings.add(toAdd);
length = textLength;
toAdd = x + " ";
}
}
toAdd = v.backspace(toAdd);
v.drawStrings.add(toAdd);
if (v.drawStrings.size() < v.lines)
v.drawLines = v.drawStrings.size();
else
v.drawLines = v.lines;
}
/**
* Draws the on-screen keyboard and displays which keys the user is
* pressing.
*/
private void drawKeyboard(Graphics g) {
int keySizeX = getWidth()/16;
int keySizeY = getHeight()/12;
Font keyboardFont = new Font("Dialog", Font.PLAIN, 24);
Graphics gr = (Graphics2D) g;
gr.setColor(new Color(0,128,128));
key keyboard[][] = k.kb;
for(int y = 0; y < keyboard.length; y++) {
for(int x = 0; x < keyboard[y].length; x++) {
int xLength = keySizeX * keyboard[y].length; // Calculates how many pixels each row will take
int leftPadding = (getWidth() - xLength)/2;
int yLength = keySizeY * keyboard.length;
int yPadding = (getHeight() - yLength);
// Font size will be calculated by window size later.
if(keyboard[y][x].specialChar)
keyboardFont = new Font("Dialog", Font.PLAIN, 24);
else
keyboardFont = new Font("Dialog", Font.PLAIN, 9);
gr.drawRect(leftPadding + x*keySizeX, yPadding + (y-1)
*keySizeY, keySizeX, keySizeY);
drawCenteredString(gr, keyboard[y][x].key, leftPadding +
x*keySizeX, yPadding + (y-1)
* keySizeY, keySizeX, keySizeY, keyboardFont);
if (v.pressedKeys.contains(keyboard[y][x].key)){
gr.fillRect(leftPadding + x*keySizeX, yPadding + (y-1)
*keySizeY, keySizeX, keySizeY);
}
}
}
}
/**
* Draws a centered string.
* Credit: https://stackoverflow.com/questions/27706197/how-can-i-center-graphics-drawstring-in-java
*/
public void drawCenteredString(Graphics gr, String text, int x, int y,
int xHeight, int yHeight, Font font) {
// Get the FontMetrics
FontMetrics metrics = gr.getFontMetrics(font);
// Determine the X coordinate for the text
int drawx = x + (xHeight - metrics.stringWidth(text)) / 2;
// Determine the Y coordinate for the text (note we add the ascent,
// as in java 2d 0 is top of the screen)
int drawy = y + ((yHeight - metrics.getHeight()) / 2) + metrics.getAscent();
// Set the font
gr.setFont(font);
// Draw the String
gr.drawString(text, drawx, drawy);
}
/**
* Draws a centered string.
*/
public void drawCenteredString(Graphics g, String text,
Rectangle rect, Font font) {
// Get the FontMetrics
FontMetrics metrics = g.getFontMetrics(font);
// Determine the X coordinate for the text
int x = rect.x + (rect.width - metrics.stringWidth(text)) / 2;
// Determine the Y coordinate for the text (note we add the ascent, as in java 2d 0 is top of the screen)
int y = rect.y + ((rect.height - metrics.getHeight()) / 2) + metrics.getAscent();
// Set the font
g.setFont(font);
// Draw the String
g.drawString(text, x, y);
}
/**
* Draws the typing prompt text
* Aligns text left and in the middle (y)
* Sets the color of each letter according to its status
*/
public void drawTypingPrompt(Graphics g, String testText,
String userText, Rectangle rect, Font font) {
FontMetrics metrics = g.getFontMetrics(font);
int x = rect.x;
int y = rect.y + ((rect.height - metrics.getHeight()) / 2)
+ metrics.getAscent();
g.setFont(font);
g.drawString(testText, x, y);
g.setColor(new Color(128,128,128));
char c = ' ';
for (int i = 0; i < testText.length(); i++) {
if(userText.length() <= i) // User hasn't typed
g.setColor(v.typingPromptColors[0]);
else if (userText.charAt(i) == testText.charAt(i))
g.setColor(v.typingPromptColors[1]);
else
g.setColor(v.typingPromptColors[2]);
c = testText.charAt(i);
int width = g.getFontMetrics(font).charWidth(c);
g.drawString("" + c, x, y);
x += width;
}
}
public void drawCenteredRect(Graphics g, Rectangle rect) {
g.drawRect(rect.x, rect.y, rect.width, rect.y);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g);
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
/**
* Handles user key presses
*/
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if(e.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
v.userString = v.backspace(v.userString);
}
else if (e.getKeyCode() == KeyEvent.VK_TAB) {
v.resetVars();
}
else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
mainFrame.dispose();
System.exit(0);
}
else if (e.getKeyChar() != '\uFFFF' && v.gameRunning){
v.userString += e.getKeyChar();
v.timingHandler();
}
String pressedKey = "" + e.getKeyChar();
if(!v.pressedKeys.contains(pressedKey)) {
v.pressedKeys.add(pressedKey.toLowerCase());
}
v.checkTest();
// Refreshes keyboard graphics to reduce visual input delay
refreshGraphics();
}
/**
* Handles key released for keyboard graphics
*/
@Override
public void keyReleased(KeyEvent e) {
String depressedKey = "" + e.getKeyChar();
v.pressedKeys.remove(depressedKey.toLowerCase());
refreshGraphics();
}
private void refreshGraphics() {
s.repaint();
}
public void windowClosing(WindowEvent e) {
mainFrame.dispose();
System.exit(0);
}
@Override
public void windowOpened(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowClosed(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowIconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowDeiconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowActivated(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowDeactivated(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
if(v.isInRect(v.rOptions, e.getPoint())) {
if(v.wordMode + 1 >= v.wordModes.length) {
v.wordMode = 0;
v.testWords = v.wordModes[0];
}
else {
v.wordMode++;
v.testWords = v.wordModes[v.wordMode];
}
v.resetVars();
}
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
+40
View File
@@ -0,0 +1,40 @@
public class keyboard {
public String engl[][] = {{"`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "backspace"},
{"tab", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "\\"},
{"caps lock", "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "enter"},
{"shift", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/", "shift"}};
public key[][] kb;
public keyboard() {
generateEngl();
}
/**
* Creates a Jagged Array of keys
*/
public void generateEngl() {
kb = new key[engl.length][];
for (int i = 0; i < engl.length; i++) {
kb[i] = new key[engl[i].length];
}
for (int y = 0; y < kb.length; y++) {
for (int x = 0; x < kb[y].length; x++) {
kb[y][x] = new key(engl[y][x]);
}
}
}
}
class key {
public String key;
public int keyID;
public boolean specialChar;
public key(String text) {
key = text;
specialChar = text.length() == 1;
}
}
+24
View File
@@ -0,0 +1,24 @@
public class language {
public String score, words, testOver, wpm, raw, accuracy, time;
// This will later load from a text file so uses can change languages
public language() {
loadLanguage();
}
private void loadLanguage() {
loadEnglish();
}
// Temporary method
private void loadEnglish() {
score = "Score";
words = " Words";
testOver = "Test Complete!";
wpm = "WPM";
raw = " (raw)";
accuracy = "Accuracy";
time = "Time";
}
}
+7
View File
@@ -0,0 +1,7 @@
public class runner {
public static void main(String[] args) {
// TODO Auto-generated method stub
gameWindow w = new gameWindow(800, 600, "Typing Teacher Alpha v1.0");
}
}
+16
View File
@@ -0,0 +1,16 @@
public class utils {
public static void main(String[] args) {
// TODO Auto-generated method stub
}
public void generateKB() {
String x = "ASDFGHJKL";
for(int i = 0; i < x.length(); i++) {
System.out.print("\"" + x.charAt(i) + "\", ");
}
}
}
+236
View File
@@ -0,0 +1,236 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
import java.awt.*;
public class variables {
public int fps = 5, lines = 3;
public boolean debug = false;
// Updating variables
private double WPM, score;
private String testString;
private String[] testWord;
private long startTime, endTime, elapsedTime;
public int typedLines, testWords, drawLines, wordMode;
public int wordModes[] = {5, 10, 25, 50, 100};
public String userString;
public String WPMText, ScoreText;
public boolean gameRunning, testOver;
public ArrayList<String> pressedKeys = new ArrayList();
public ArrayList<String> words = new ArrayList();
public ArrayList<String> drawStrings = new ArrayList();
public ArrayList<String> userInputStrings = new ArrayList();
// to do:
// Finish test when last word is spelled right
// calculate real WPM and actual WPM
boolean repeatWords, timerRunning;
Color typingPromptColors[], backgroundColor, textColor;
Rectangle rOptions, rScore, rWPM, rTopBar;
Random r = new Random();
public variables() {
loadSettings();
loadWords();
resetVars();
generateNewTest();
generateThemes();
}
public void resetVars() {
userString = "";
testString = "";
typedLines = 0;
generateNewTest();
timerRunning = false;
elapsedTime = -1;
WPM = 0;
score = 0;
drawLines = lines;
gameRunning = true;
testOver = false;
}
public void loadSettings() {
// This will load from a config file later.
wordMode = 1;
testWords = wordModes[wordMode];
repeatWords = false;
}
/**
* typingPromptColors
* 0 = not typed
* 1 = correctly typed
* 2 = incorrectly typed
*/
public void generateThemes() {
typingPromptColors = new Color[3];
typingPromptColors[0] = new Color(128,128,128);
typingPromptColors[1] = new Color(0,0,0);
typingPromptColors[2] = new Color(255,128,128);
backgroundColor = new Color(255,255,255);
textColor = new Color(0,0,0);
}
public void loadWords() {
try {
File myObj = new File("words.txt");
Scanner myReader = new Scanner(myObj);
while (myReader.hasNextLine()) {
String data = myReader.nextLine();
words.add(data);
}
myReader.close();
} catch (FileNotFoundException e) {
System.out.println("Could not find words file");
e.printStackTrace();
}
}
/**
* Generates new test
* Called when program is first started and when user requests a new one.
*/
public void generateNewTest() {
testWord = generateRandomWords();
testString = "";
for (String x : testWord)
testString += x + " ";
testString = backspace(testString);
}
/**
* Generates 'size' amount of random words
* Can only draw the same word once
*/
public String[] generateRandomWords() {
String[] toReturn = new String[testWords];
ArrayList<Integer> usedWords = new ArrayList();
int wordChoice = r.nextInt(words.size());
if(!repeatWords) {
for(int i = 0; i < testWords; i++) {
while(usedWords.contains(wordChoice))
wordChoice = r.nextInt(words.size());
usedWords.add(wordChoice);
toReturn[i] = words.get(wordChoice);
}
}
else {
for(int i = 0; i < testWords; i++) {
wordChoice = r.nextInt(words.size());
toReturn[i] = words.get(wordChoice);
}
}
return toReturn;
}
/**
* Checks if user has completed test
* Called when user presses key
*/
public void checkTest() {
String lastWordOfTest = testString.substring(testString.lastIndexOf(" ") + 1);
String lastWordOfUser = userString.substring(userString.lastIndexOf(" ") + 1);
if(userString.length() == testString.length() && lastWordOfTest.equals(lastWordOfUser)) {
stopTimer();
gameRunning = false;
testOver = true;
}
}
public String backspace(String str) {
if (str != null && str.length() > 0) {
str = str.substring(0, str.length() - 1);
}
return str;
}
/**
* Called when user presses key
* Updates game stats to prevent delayed info
*/
public void timingHandler() {
if(!timerRunning) { // Starts test
startTimer();
timerRunning = true;
}
calculateGameStats();
}
public void startTimer() {
startTime = System.nanoTime();
}
public void stopTimer() {
if(timerRunning)
endTime = System.nanoTime();
timerRunning = false;
calculateGameStats();
}
public void calculateGameStats() {
if(timerRunning)
elapsedTime = (System.nanoTime() - startTime)/10000;
else
elapsedTime = (endTime - startTime)/10000;
WPM = (double) userString.length() / 5 / elapsedTime * (60 / 0.00001);
WPM = round(WPM, 2);
}
public double calculateAccuracy() {
int counter = 0;
for(int i = 0; i < testString.length(); i++) {
if(testString.charAt(i) == userString.charAt(i))
counter++;
}
double toReturn = round((double)(counter)/testString.length(), 3);
return toReturn * 100;
}
public double round(double number, int places) {
long shift = (long) Math.pow(10, places);
double shifted = number * shift;
shifted = Math.round(shifted);
return (double) (shifted)/shift;
}
public void setTestSize(int x) {
testWords = x;
}
public String getString() {
return testString;
}
public String[] getTestWords() {
return testWord;
}
public double getWPM() {
return WPM;
}
public String generateElapsedTimeString() {
double time = ((double) (elapsedTime / 1000))/100;
return time + "s";
}
public Long getElapsedTime() {
return elapsedTime;
}
/**
* Checks if a specified point is inside a rectangle
* @param r the rectangle
* @param p the point
*/
public boolean isInRect(Rectangle r, Point p) {
return r.x <= p.x && r.x + r.width >= p.x
&& r.y <= p.y && r.y + r.height >= p.y;
}
}
+1000
View File
File diff suppressed because it is too large Load Diff