Skip to content

Instantly share code, notes, and snippets.

@LouisJenkinsCS
Last active November 2, 2015 00:07
Show Gist options
  • Save LouisJenkinsCS/dd4d5dc601f407fd81fd to your computer and use it in GitHub Desktop.
Save LouisJenkinsCS/dd4d5dc601f407fd81fd to your computer and use it in GitHub Desktop.
/*
Interface which every GameObject must implement.
*/
public interface GameObject {
// Called when an object needs to be updated.
void update();
// Called when a collision was detected. The obj argument is the other object it collided with.
void onCollision(GameObject obj);
}
// Singleton because you only ever want one GameWorld.
public class GameWorld {
private static final GameWorld world = new GameWorld();
/*
We maintain a list of all game objects to be iterated over. A better data structure most likely exists, but this is an example.
*/
private static final List<GameObject> list = new ArrayList<>();
/*
A lockfree queue that can serve as an event queue for runnable tasks. Pretty much, after polling on the list of
GameObjects it will then poll on this queue until it is empty, and go back to polling other things. Once again, it is
naive, it expects the task to be very short, as a blocking operation will stall the entire game.
*/
private static final ConcurrentLinkedQueue<Runnable> eventQueue = new ConcurrentLinkedQueue<>();
public static GameWorld getInstance(){
return world;
}
/*
As we do not want to update the collection while polling over it, we add it to the eventQueue to be done later.
*/
public void registerObject(GameObject obj){
eventQueue.add(new Runnable() {
@Override
public void run(){
list.add(obj);
}
});
}
public void unregisterObject(GameObject obj){
eventQueue.add(new Runnable() {
@Override
public void run(){
list.remove(obj);
}
});
}
/*
Very naive event loop, polls through the list of objects and updates it each time.
*/
public void loop(){
for(GameObject obj: list){
obj.update(this);
}
Runnable task;
while((task = eventQueue.poll()) != null){
task.run();
}
render();
// Just to make sure we don't burn out the CPU.
sleep(2);
}
// Other stuff
}
public class Bullet implements GameObject {
// In milliseconds, bullets will be updated on this interval.
protected static final int BULLET_INTERVAL = 10;
private long lastUpdate;
public Bullet(Point3d coordinates, Point3d direction, GameWorld state){
/*
Coordinates can be updated, direction is a vector which signifies where it moves each second
and state can contain things like wind-factor and resistance, etc.
*/
}
/*
By obtaining the currentTimeMillis, we naively believe the user has not altered his computer's time to get
a bit of an advantage, but this isn't meant to be a simple solution to the problem. By checking each time
we get to update it after a certain amount of time has ellapsed, while keeping it synchronized with the
rest of the game.
*/
@Override
void update(){
long time = currentTimeMillis();
if(time > (lastUpdate - BULLET_INTERVAL)){
// It's been enough time, time to update the bullet.
// Manipulate bullet based on current coordinates, direction, and state of the game, gotten from constructor.
}
}
@Override
void onCollision(GameObject obj){
// Can pass through players, cannot pass through the ground.
if(obj instanceof Ground){
GameWorld.getInstance().unregisterObject(this);
}
}
}
public class Ground implements GameObject {
@Override
void update(){
// Nothing, it's the ground.
}
@Override
void onCollision(GameObject obj){
if(obj instanceof Bullet){
// maybe change bitmap picture to have a dent there?
}
}
}
public class Player implements GameObject {
@Override
void onCollision(GameObject obj){
if(obj instanceof Bullet){
// Decrease HP(?)
}
if(obj instanceof Ground){
// Walk on it, if the Z-axis is positive, it is on an upward slope, hence player's Z-axis should increase as well. Etc.
}
}
@Override
void update(){
// Move player, check if something collided with him, interact with world, etc. Can even poll for user input.
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment