Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Conflicts:
	src/game/RhythmState.java
  • Loading branch information
Peachball committed Mar 31, 2018
2 parents 211da8f + 43a9285 commit a5a8441
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 48 deletions.
20 changes: 20 additions & 0 deletions src/game/Beat.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package game;

public class Beat {
int x; //x position of the beat circle
int y; //y position of the beat circle
int time; //time, in ms, of the beat from the beginning of the song
//Clip hitSound; to be used later, when sounds are added

public Beat() {
this.x = 0;
this.y = 0;
this.time = 0;
}

public Beat(int x, int y, int time) {
this.x = x;
this.y = y;
this.time = time;
}
}
27 changes: 27 additions & 0 deletions src/game/BeatmapParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package game;

import java.util.LinkedList;

public class BeatmapParser {

public LinkedList<Beat> parseBeatmap() {
LinkedList<Beat> beatlist = new LinkedList<Beat>();
beatlist.add(new Beat(100,78,854));
beatlist.add(new Beat(42,276,3132));
beatlist.add(new Beat(235,324,3891));
beatlist.add(new Beat(465,104,5410));
beatlist.add(new Beat(256,192,5790));
beatlist.add(new Beat(263,259,9398));
beatlist.add(new Beat(476,172,10347));
beatlist.add(new Beat(359,44,11106));
beatlist.add(new Beat(9,68,12436));
beatlist.add(new Beat(41,308,14144));
beatlist.add(new Beat(367,364,15474));
beatlist.add(new Beat(384,114,16423));
beatlist.add(new Beat(312,43,16803));
beatlist.add(new Beat(225,92,17182));
beatlist.add(new Beat(67,248,18701));
beatlist.add(new Beat(141,314,19081));
return beatlist;
}
}
24 changes: 24 additions & 0 deletions src/game/HitObject.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package game;

public class HitObject {
int x;
int y;
float radius;
float duration;
boolean clicked = false;

public HitObject() {
this.x = 0;
this.y = 0;
this.radius = 0;
this.duration = 0;
}

public HitObject(int x, int y, float radius, float duration, boolean clicked) {
this.x = x;
this.y = y;
this.radius = radius;
this.duration = duration;
this.clicked = clicked;
}
}
106 changes: 58 additions & 48 deletions src/game/RhythmState.java
Original file line number Diff line number Diff line change
@@ -1,35 +1,39 @@
package game;

import java.util.LinkedList;
import java.util.concurrent.CopyOnWriteArrayList;

import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Circle;
import org.newdawn.slick.geom.Line;
import org.newdawn.slick.geom.Vector2f;
import org.newdawn.slick.state.StateBasedGame;

public class RhythmState extends DefaultGameState{

public final int[] CLICK_KEYS = {Input.KEY_Z, Input.KEY_X};
public final float CIRCLE_TIME = 400f; //time it takes for circles to shrink. the time the circles are on screen is double this, as the circles grow, then shrink.

private Vector2f curpos = new Vector2f(); //position of the current circle (shrinking circle)
private Vector2f nextCircle = new Vector2f(); //position of the next circle (growing circle)
private float prevCircleSize = 0; //current circle size
private float nextCircleSize = 0; //next circle size
public final float CIRCLE_TIME = 1000f; //time it takes for approach circles to shrink.
public final float LENIENCE_TIME = 200f; //lenience, in ms, given to the player to click the hit object

private float circleTime = -1f; //changing this doesn't do anything. must be negative, however
private Image background; //background image
private float timescale = .10f; //rate at which circles shrink. doesn't change the time circles are on screen, however
private float timescale = .08f; //rate at which approach circles shrink. doesn't change the time circles are on screen, however
private int points = 0; //total number of points
private boolean clicked = false; //whether or not the current circle has been clicked
private boolean nextcircleclicked = false; //whether or not the next circle has been clicked

private float maxRadius = CIRCLE_TIME * timescale; //maximum radius of the circles

private float maxRadius = CIRCLE_TIME * timescale; //maximum radius of the approach circles
private float innerRadius = 20f; //radius of the inner hit circles which you click

private long starttime = System.currentTimeMillis(); //initial time
private long songtime = 0; //time since beginning of the song, in ms

private CopyOnWriteArrayList<HitObject> hitobjects = new CopyOnWriteArrayList<>();
private LinkedList<Beat> beatmap = new LinkedList<>();
private int beatmapindex = 0;

private Input inp; // Get various information about input (e.g. mouse position)

Expand All @@ -48,6 +52,9 @@ public int getID() {
public void init(GameContainer gc, StateBasedGame arg1) throws SlickException {
background = new Image("res/background.jpg");
background = background.getScaledCopy(gc.getWidth(), gc.getHeight());

BeatmapParser beatmapparser = new BeatmapParser();
beatmap = beatmapparser.parseBeatmap();
}

@Override
Expand All @@ -57,48 +64,50 @@ public void leave(GameContainer arg0, StateBasedGame arg1) throws SlickException
@Override
public void render(GameContainer gc, StateBasedGame arg1, Graphics g) throws SlickException {
g.drawImage(background, 0, 0);
g.setColor(Color.cyan);
g.setLineWidth(10f);
g.drawLine(curpos.x, curpos.y, nextCircle.x, nextCircle.y);
if (nextcircleclicked) {
g.setColor(Color.green);
} else {
g.setColor(Color.cyan);
}
g.fill(new Circle(nextCircle.x, nextCircle.y, nextCircleSize));
if (clicked) {
g.setColor(Color.green);
} else {
g.setColor(Color.cyan);

for (HitObject hitobject:hitobjects) { //this for loop draws all the hit objects
int index = hitobjects.indexOf(hitobject);
if (index != hitobjects.size() - 1) { //check to make sure hitobject is not the last in the list
g.setLineWidth(5f);
g.setColor(Color.white);
g.draw(new Line(new Vector2f(hitobject.x, hitobject.y), new Vector2f(hitobjects.get(index+1).x, hitobjects.get(index+1).y))); //draws a line in between consecutive hit objects
}
if (hitobject.clicked) { //changes color based on the state of the circle
g.setColor(Color.green);
} else {
g.setColor(Color.white);
}
g.setLineWidth(2f);
g.draw(new Circle(hitobject.x, hitobject.y, hitobject.radius+innerRadius)); //draws approach circle
g.fill(new Circle(hitobject.x, hitobject.y, innerRadius)); //draws hit circle
}
g.fill(new Circle(curpos.x, curpos.y, prevCircleSize));

g.setColor(Color.white);
g.drawString("Points: " + points, gc.getWidth() - 200, 50);
g.drawString("Points per second " + 1000f * points / (System.currentTimeMillis() - starttime), gc.getWidth() - 600, 70);
}

@Override
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
if (circleTime < 0) {
// interval from radius to width - radius
maxRadius = CIRCLE_TIME * timescale;
curpos.set(nextCircle);
nextCircle = new Vector2f((float) randomRange(maxRadius, gc.getWidth() - maxRadius),
(float) randomRange(maxRadius, gc.getHeight() - maxRadius));
circleTime = CIRCLE_TIME * timescale;
clicked = nextcircleclicked;
nextcircleclicked = false;
}
else {
circleTime -= delta * timescale;
songtime += delta;

if (beatmapindex<=beatmap.size()-1&&beatmap.get(beatmapindex).time<=CIRCLE_TIME+songtime) { //puts objects in the beatmap into the hitobjects list when needed
Beat currentbeat = beatmap.get(beatmapindex);
HitObject hitobject = new HitObject(currentbeat.x, currentbeat.y, maxRadius, CIRCLE_TIME, false);
hitobjects.add(hitobject);
beatmapindex++;
}
prevCircleSize = circleTime;
nextCircleSize = maxRadius - prevCircleSize;

}
if (!hitobjects.isEmpty()) {
for (HitObject hitobject:hitobjects) {
int index = hitobjects.indexOf(hitobject);
hitobjects.set(index, new HitObject(hitobject.x, hitobject.y, maxRadius * (hitobject.duration / CIRCLE_TIME), hitobject.duration - delta, hitobject.clicked)); //shrinks approach circle and reduces remaining time on screen
if (hitobject.duration<=-LENIENCE_TIME||hitobject.clicked&&hitobject.duration<=0) { //removes hit circle if time left is less than or equal to the lenience time, or the circle has already been clicked and it's time left is less than zero
hitobjects.remove(index);
}
}
}

private double randomRange(float lower, float upper) {
return Math.random() * (upper - lower) + lower;
}

@Override
Expand All @@ -108,15 +117,16 @@ public boolean isAcceptingInput() {

public void click() {
int x = inp.getMouseX(), y= inp.getMouseY();
if (!clicked&&new Vector2f(x, y).distance(curpos) < prevCircleSize) { //checks if current circle has already been clicked, then checks if click is within the circle
clicked = true;
points ++;
} else if (!nextcircleclicked&&new Vector2f(x, y).distance(nextCircle) < nextCircleSize){ //checks if next circle has already been clicked, then checks if click is within the circle
nextcircleclicked = true;
points ++;
for (HitObject hitobject:hitobjects) {
if (!hitobject.clicked&&new Vector2f(x, y).distance(new Vector2f(hitobject.x, hitobject.y)) < innerRadius) { //checks if current circle has already been clicked, then checks if click is within the circle
hitobjects.set(hitobjects.indexOf(hitobject), new HitObject(hitobject.x, hitobject.y, hitobject.radius, hitobject.duration, true)); //changes hitobject click state
points++; //increments points
break; //breaks out of for loop so that only one hit object is clicked at once
}
}
}


@Override
public void mousePressed(int button, int x, int y) {
if (button == Input.MOUSE_LEFT_BUTTON) {
Expand Down

0 comments on commit a5a8441

Please sign in to comment.