Skip to content

Instantly share code, notes, and snippets.

@riccardobl
Created July 8, 2015 17:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save riccardobl/8f47ee6351fcb4897f86 to your computer and use it in GitHub Desktop.
Save riccardobl/8f47ee6351fcb4897f86 to your computer and use it in GitHub Desktop.
import com.jme3.app.SimpleApplication;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Quad;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JOptionPane;
public class SnakeJME extends SimpleApplication implements ActionListener{
// Settings
private final byte _TILES_N=20;
private final float _TILE_SIZE=1;
private final byte _SNAKE_SPEED=6; // speed in tiles per sec
private final byte _INITIAL_LENGTH=3;
// ----
private enum Directions{
X(new Vector3f(1,0,0)),
mX(new Vector3f(-1,0,0)),
Y(new Vector3f(0,1,0)),
mY(new Vector3f(0,-1,0)),
NONE(new Vector3f(0,0,0));
private Vector3f x;
private Directions(Vector3f d){
x=d;
}
public Vector3f getDirection(){
return x;
}
}
private final Random _RANDOM=new Random(System.currentTimeMillis());
private final float _TPS_DELAY=1f/_SNAKE_SPEED;
private Node TERRAIN;
private float TIME_FROM_UPDATE=0;
private ArrayList<Geometry> SNAKE=new ArrayList<Geometry>();
private Directions SNAKE_DIRECTION=Directions.NONE;
private ArrayList<Geometry> BLIPS=new ArrayList<Geometry>();
private String INPUT;
public static void main(String[] s) {
new SnakeJME().start();
}
@Override
public void simpleInitApp() {
bindKeys();
cam.setLocation(new Vector3f(0,0,30));
flyCam.setEnabled(false);
prepareTerrain();
spawnBlip();
// Build snake
int tiles_n_half=_TILES_N/2;
for(byte i=0;i<_INITIAL_LENGTH;i++)SNAKE.add(makeSprite(tiles_n_half,tiles_n_half,ColorRGBA.Orange));
}
@Override
public void simpleUpdate(float tpf) {
TIME_FROM_UPDATE+=tpf;
if(TIME_FROM_UPDATE>=_TPS_DELAY){
TIME_FROM_UPDATE=0;
if(updateSnake()){
JOptionPane.showMessageDialog(null,"Game Over.");
stop();
}
}
}
private boolean updateSnake() { // return true = dead
if(INPUT!=null){
switch(INPUT){
case "W":
if(SNAKE_DIRECTION!=Directions.mY)SNAKE_DIRECTION=Directions.Y;
break;
case "A":
if(SNAKE_DIRECTION!=Directions.X)SNAKE_DIRECTION=Directions.mX;
break;
case "D":
if(SNAKE_DIRECTION!=Directions.mX)SNAKE_DIRECTION=Directions.X;
break;
case "S":
if(SNAKE_DIRECTION!=Directions.Y)SNAKE_DIRECTION=Directions.mY;
break;
}
}
if(SNAKE_DIRECTION==Directions.NONE) return false;
Geometry oldhead=SNAKE.get(0);
Vector3f future_pos=oldhead.getLocalTranslation().add(SNAKE_DIRECTION.getDirection().mult(_TILE_SIZE));
// Check if the snake is eating itself
for(Geometry s:SNAKE)if(s.getLocalTranslation().equals(future_pos))return true;
// Check if the snake is eating something good
for(Geometry s:BLIPS){
if(s.getLocalTranslation().equals(future_pos)){
eatBlip(s);
SNAKE.add(0,s);
s.getMaterial().setColor("Color",ColorRGBA.Orange);
s.setLocalTranslation(future_pos);
return false;
}
}
// Check if snake is falling out the world
float sx=_TILE_SIZE*_TILES_N;
if(future_pos.x>=sx||future_pos.x<0||future_pos.y>=sx||future_pos.y<0)return true;
Geometry newhead=SNAKE.remove(SNAKE.size()-1); // Move the latest sprite on the head of snake
SNAKE.add(0,newhead);
newhead.setLocalTranslation(future_pos);
return false;
}
private void spawnBlip() {
int x=_RANDOM.nextInt(_TILES_N);
int y=_RANDOM.nextInt(_TILES_N);
Geometry blip=makeSprite(x,y,ColorRGBA.randomColor());
BLIPS.add(blip);
}
private void eatBlip(Geometry blip) {
BLIPS.remove(blip);
spawnBlip();
}
@Override
public void onAction(String name, boolean isPressed, float tpf) {
if(isPressed) INPUT=name;
}
private Geometry makeSprite(int x, int y, ColorRGBA color) {
Quad q=new Quad(_TILE_SIZE,_TILE_SIZE);
Geometry g=new Geometry("Terrain",q);
Material m=new Material(assetManager,"Common/MatDefs/Misc/Unshaded.j3md");
g.setMaterial(m);
m.setColor("Color",color);
TERRAIN.attachChild(g);
g.setLocalTranslation(x*_TILE_SIZE,y*_TILE_SIZE,0f);
return g;
}
private void prepareTerrain() {
Quad q=new Quad(_TILE_SIZE*_TILES_N,_TILE_SIZE*_TILES_N);
Geometry g=new Geometry("Terrain",q);
Material m=new Material(assetManager,"Common/MatDefs/Misc/Unshaded.j3md");
g.setMaterial(m);
m.setColor("Color",ColorRGBA.Brown);
TERRAIN=new Node();
TERRAIN.attachChild(g);
rootNode.attachChild(TERRAIN);
TERRAIN.center();
}
private void bindKeys() {
inputManager.addMapping("W",new KeyTrigger(KeyInput.KEY_W),new KeyTrigger(KeyInput.KEY_UP));
inputManager.addMapping("A",new KeyTrigger(KeyInput.KEY_A),new KeyTrigger(KeyInput.KEY_LEFT));
inputManager.addMapping("S",new KeyTrigger(KeyInput.KEY_S),new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addMapping("D",new KeyTrigger(KeyInput.KEY_D),new KeyTrigger(KeyInput.KEY_RIGHT));
inputManager.addListener(this,"W","A","S","D");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment