Android Open Source - android-jplay J Play






From Project

Back to project page android-jplay.

License

The source code is released under:

Copyright (c) Nikolaj Baer All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. ...

If you think the Android project android-jplay listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.nikolajbaer.awtrender;
/*  w ww . j a  va  2 s . c  o  m*/
/* java */
import java.util.ArrayList;
import java.util.HashMap;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/* jbox2d */
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.*;

/* AWT */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.*;
import java.awt.geom.*;

/* local */
import com.nikolajbaer.render.Renderable;
import com.nikolajbaer.render.RenderObject;
import com.nikolajbaer.game.objects.*;
import com.nikolajbaer.Util;
import com.nikolajbaer.game.*;
import com.nikolajbaer.game.players.*;
import com.nikolajbaer.game.weapons.*;

public class JPlay extends JFrame implements ActionListener { //implements Runnable{
    private Game m_game;
    private Timer m_timer;
    private BufferedImage m_backBuffer ;
    private Graphics2D m_backGraphics;
    private HashMap<String,AWTRenderObject> m_renderObjects;
    private HashMap<Integer,Boolean> m_keyMap;

    // pixels per meter
    public static final float PPM = 10.0f;
    private int m_gameWidth=600;
    private int m_gameHeight=800;
    private int m_screenWidth=400;
    private int m_screenHeight=600;
    private double m_zoom=1.0;
    private double m_zoom2=0.5;
    private float m_playerAngle;
    private Vec2 m_playerPos;

    public JPlay(String name){
        super(name);

        m_renderObjects=new HashMap<String,AWTRenderObject>();

        setSize(m_screenWidth,m_screenHeight);//m_gameWidth+10,m_gameHeight+20);
        m_backBuffer = new BufferedImage( m_gameWidth,m_gameHeight, BufferedImage.TYPE_INT_RGB ) ;
        m_backGraphics = (Graphics2D)m_backBuffer.getGraphics();
        //m_backGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        int gwidth=(int)(m_gameWidth/PPM);
        int gheight=(int)(m_gameHeight/PPM);
        m_game=new Game(gwidth,gheight); // game is in meters
        Game.game=m_game;
        m_timer = new Timer(1000/40,this);
        m_timer.setInitialDelay(500);
        m_timer.start(); 
       
        m_keyMap=new HashMap<Integer,Boolean>(); 

        addKeyListener(new KeyListener(){
            public void keyPressed(KeyEvent e){
                m_keyMap.put(e.getKeyCode(),true);
            }

            public void keyReleased(KeyEvent e){
                m_keyMap.put(e.getKeyCode(),false);
            }
            public void keyTyped(KeyEvent e){}
        });
    
        addMouseListener(new MouseListener(){
            public void mouseClicked(MouseEvent e){
                //m_game.getPlayer().rotateToPointAt(toWorld(e.getX()),toWorld(e.getY()));
            }
            public void mouseExited(MouseEvent e){ }
            public void mouseReleased(MouseEvent e){ }
            public void mouseEntered(MouseEvent e){ }
            public void mousePressed(MouseEvent e){ }
        });

        // Add Players
        float[] verts={-2.4f,3.2f,-2.4f,-3.2f,2.4f,-3.2f,2.4f,3.2f};

        // Spread the players out in a ring 
        Vec2 mid=new Vec2(gwidth/2.0f,gheight/2.0f);
        Vec2 offset=new Vec2(gwidth/2*0.75f,0);
        int np=2; //6;
        for(int i=0;i<np;i++){
            Body b=m_game.createRect(0.2f,-2.4f,-3.2f,4.8f,6.4f);
            //Body b=m_game.createPolygon(1.0f, verts );

            double a=(2*Math.PI)/np;
            Vec2 rv=Util.rotate( offset, (float)(i*a) );
            float ra=(float)(i*a < Math.PI ? i*a+Math.PI : i*a-Math.PI);
            b.setXForm( mid.add(rv) ,(float)(ra+Math.PI/2)); // i guess it goes from 0,1 not 1,0
            PlayerObject po=new PlayerObject(b,verts);
            // arm the tank
            po.addWeapon(0,new TankCannon());
            po.addWeapon(1,new Blaster());
            po.selectWeapon(0);
            // and add ai or player
            if(i==0){ 
                m_game.addPlayer(new LivePlayer(po),true);
            }else{
                m_game.addPlayer(new LambPlayer(po));
            }
        }
        m_game.addObstacle(3,3);
    }

    private Boolean getKey(int k){
        Boolean b= m_keyMap.get(k);
        return b != null && b;
    }

    private void processKeyActions(){
        // TODO be smarter about end-game state
        if(m_game.getPlayer().getBody()==null){ return; }

        if(getKey(KeyEvent.VK_SPACE)){
            m_game.getPlayer().triggerOn();
        }else{
            m_game.getPlayer().triggerOff();
        }

        // zoomer hotkey
        if(getKey(KeyEvent.VK_SHIFT)){
            if(m_zoom>m_zoom2){ 
                m_zoom-=0.1;
            }else{
                m_zoom=m_zoom2;
            }
        }else{
            if(m_zoom<1.0){ 
                m_zoom+=0.1;
            }else{
                m_zoom=1.0;
            }
        }

        if(getKey(KeyEvent.VK_LEFT)){
            m_game.getPlayer().left();
        }else if(getKey(KeyEvent.VK_RIGHT)){
            m_game.getPlayer().right();
        }
        
        if(getKey(KeyEvent.VK_UP)){
            m_game.getPlayer().forward();
        }else if(getKey(KeyEvent.VK_DOWN)){
            m_game.getPlayer().reverse();
        }else{
            m_game.getPlayer().halt();
        } 


        if(getKey(KeyEvent.VK_1)){
            m_game.getPlayer().selectWeapon(0);
        }else if(getKey(KeyEvent.VK_2)){
            m_game.getPlayer().selectWeapon(1);
        }else if(getKey(KeyEvent.VK_3)){
            m_game.getPlayer().selectWeapon(2);
        }



        // Read from accelerometer
        // CONSIDER would need to adjust for starting position on phone..
        // NOTE this stopped working o nmy laptop due to grahnix
        /*
        float[] accel=readAccel();
        float x=accel[0];
        float y=accel[1]; 
        System.out.println("accel "+x+","+y);
        Vec2 i=new Vec2(x,y);
        if(x > 0.5){
            m_game.getPlayer().left();
        }else if(x < -0.5){
            m_game.getPlayer().right();
        }
        if(y > 0.5){
            m_game.getPlayer().forward();
        }else if(y < -0.5){
            m_game.getPlayer().reverse();
        }
        Vec2 d=m_game.getPlayer().getDir();
        float a=Vec2.cross(i,d);
        //System.out.println("applying torque "+a);
        if(i.length()>0.3){ 
            if(Vec2.dot(i,d) < 0){
                //m_game.getPlayer().reverse();
            }else{
                //m_game.getPlayer().setThrottle(i.length());
            }
        }else{ 
            m_game.getPlayer().halt();
        }
        //m_game.getPlayer().forward();

        Body b=m_game.getPlayer().getBody();
        b.wakeUp();
        //b.applyTorque(a*-400);
        //b.applyTorque(a*10);
        */
    }

    // Use this to help develop phone-like control system
    private float[] readAccel(){
        // never understood why there can't be some simpler defaults for java..
        File file = new File("/sys/devices/platform/hdaps/position");
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        DataInputStream dis = null;
        float x=0;
        float y=0;
        try {
            fis = new FileInputStream(file);
            dis = new DataInputStream(fis);
            String l=dis.readLine();
            l=l.replace("(","").replace(")","");
            String[] tokens = l.split(",");
            // 0 - flat is -500, goes from ~-600 left to -300 right down
            // 1 - flat is 500, goes from 600 tipped forward to 300 tipped back
            x=(Float.parseFloat(tokens[0])+500)/150.0f;
            y=(Float.parseFloat(tokens[1])-500)/150.0f;
            // Now x is left/right, with left full as -150, right full as 150
            // y is front/back with tipped forward full as -150, back full is 150
            fis.close();
            dis.close();
        } catch (FileNotFoundException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        }
        return new float[]{x,y};
    }

    public void actionPerformed(ActionEvent e) {
        processKeyActions();
        m_game.tick();
        render();
    }

    public static void main(String[] args) {
        JPlay f = new JPlay("JPlay");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }

    public void render( ) {
        // render to back buffer
        m_backGraphics.setColor( Color.black ) ;
        m_backGraphics.fillRect( 0,0, m_screenWidth,m_screenHeight) ;
        // render game field
        //m_game.draw(m_backGraphics);
        //m_backGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        AffineTransform t0=m_backGraphics.getTransform();

        if(m_game.getPlayer().getBody()!=null){
            Body pb=m_game.getPlayer().getBody();
            m_playerPos=toScreen(pb.getPosition());
            m_playerAngle=pb.getAngle();
        }
        
        // Translate to user position
        // and then offset to center of screen
        
        m_backGraphics.translate(m_screenWidth/2,m_screenHeight/2);

        /*if(m_zoom!=1.0){
            m_backGraphics.scale(m_zoom,m_zoom);
        } */
        m_backGraphics.scale(0.5,0.5);

        m_backGraphics.rotate(-m_playerAngle);
        m_backGraphics.translate(-m_playerPos.x,-m_playerPos.y);

        m_backGraphics.setColor( Color.gray ) ;
        m_backGraphics.drawRect( 0,0, m_gameWidth,m_gameHeight) ;


        ArrayList<Renderable> renderables=m_game.getRenderables();
        AffineTransform t=m_backGraphics.getTransform();
        for(int i=0;i<renderables.size(); i++){
            Renderable r=renderables.get(i);
            AWTRenderObject ro=(AWTRenderObject)r.getRenderObject(); 
            if(ro==null){
                // TODO lookup render object via key
                // get render key  
                String k=r.getRenderKey();
                // if in m_renderObjects, then attach that,
                ro=m_renderObjects.get(k);
                // otherwise create a new one from the renderobject factory 
                // CONSIDER do i want a factory to be retrieved or an instance?
                if(ro==null){
                    // TODO add a renderobjectfactory abstract class
                    // that i can override for each render lib
                    System.out.println("Building a "+k+" Render Object");
                    //ro=new PolygonRenderObject();
                    if(k=="obstacle"){
                        int gs=(int)toScreen(m_game.OBSTACLE_GRID_SIZE);
                        ro=new RectRenderObject(gs,gs);
                    }else{
                        ro=new PNGRenderObject("res/drawable/"+k+".png");
                    }
                    m_renderObjects.put(k,ro);
                }
                r.setRenderObject(ro);
            }
            float[] wt=r.getWorldTransform();
            ro.setGraphics(m_backGraphics);
            ro.setPixelRatio(PPM);
            ro.renderFromWorld(wt[0],wt[1],wt[2]);
            // TODO draw sprite k at location t
            // CONSIDER sprite lookup is expensive, should embed it in renderable as renderobject
            //  and call .renderAtTransform(), maybe setup graphics first or something..
            m_backGraphics.setTransform(new AffineTransform(t));
        }
      
        //reset to original trnasform 
        m_backGraphics.setTransform(new AffineTransform(t0)); 
        Graphics g = getGraphics();
        g.drawImage( m_backBuffer, 5,25, null );
        g.dispose();
    }    

    /* Convert world/screen */
    private float[] toWorld(float[] n){
        if(n==null){ return null; }
        float[] r=new float[n.length];
        for(int i=0;i<n.length;i++){
            r[i]=toWorld(n[i]);
        }
        return r;
    }

    private Vec2 toWorld(Vec2 v){
        return new Vec2(toWorld(v.x),toWorld(v.y));
    }

    private float[] toScreen(float[] n){
        if(n==null){ return null; }
        float[] r=new float[n.length];
        for(int i=0;i<n.length;i++){
            r[i]=toWorld(n[i]);
        }
        return r;
    }

    private float toWorld(int n){ return toWorld((float)n); }

    private float toWorld(float n){
        return n/PPM;
    }

    private float toScreen(float n){
        return n*PPM;
    }

    private Vec2 toScreen(Vec2 v){
        return new Vec2(toScreen(v.x),toScreen(v.y));
    }

}




Java Source Code List

com.nikolajbaer.Util.java
com.nikolajbaer.androidrender.AndroidRenderObject.java
com.nikolajbaer.androidrender.DotRenderObject.java
com.nikolajbaer.androidrender.DrawableRenderObject.java
com.nikolajbaer.androidrender.JPlayActivity.java
com.nikolajbaer.androidrender.JPlayThread.java
com.nikolajbaer.androidrender.JPlayView.java
com.nikolajbaer.androidrender.PolygonRenderObject.java
com.nikolajbaer.awtrender.AWTRenderObject.java
com.nikolajbaer.awtrender.JPlay.java
com.nikolajbaer.awtrender.PNGRenderObject.java
com.nikolajbaer.awtrender.PolygonRenderObject.java
com.nikolajbaer.awtrender.RectRenderObject.java
com.nikolajbaer.game.Game.java
com.nikolajbaer.game.objects.BulletObject.java
com.nikolajbaer.game.objects.GameObjectEventListener.java
com.nikolajbaer.game.objects.GameObjectEvent.java
com.nikolajbaer.game.objects.GameObject.java
com.nikolajbaer.game.objects.ObstacleObject.java
com.nikolajbaer.game.objects.PlayerObject.java
com.nikolajbaer.game.objects.PolygonGameObject.java
com.nikolajbaer.game.objects.ShrapnelObject.java
com.nikolajbaer.game.players.GamePlayer.java
com.nikolajbaer.game.players.HunterPlayer.java
com.nikolajbaer.game.players.LambPlayer.java
com.nikolajbaer.game.players.LivePlayer.java
com.nikolajbaer.game.weapons.Blaster.java
com.nikolajbaer.game.weapons.TankCannon.java
com.nikolajbaer.game.weapons.Weapon.java
com.nikolajbaer.render.RenderObject.java
com.nikolajbaer.render.Renderable.java