Android Open Source - android-jplay J Play Thread






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.androidrender;
//ww w. j av a2  s  .  c  o m
/* java */
import java.util.ArrayList;
import java.util.HashMap;

/* android */
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RectShape;
import android.view.MotionEvent;

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

/* 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.androidrender.R;


public class JPlayThread extends Thread { 
    private static final String TAG = "JPlayThread";
    
    private boolean mRun;
    private RectF mScreenRect;
    private Paint mClearPaint;
    private Paint mGameAreaPaint;
    private SurfaceHolder mSurfaceHolder;
    private Context mContext;
    
    /* rendering tools */ 
    private HashMap<String,AndroidRenderObject> m_renderObjects;
    private HashMap<Integer,Boolean> m_keyMap;
    
    /* game items */
    private Game m_game;
    public static final float PPM = 10.0f;
    // TODO feed this from what is determined on creation
    private int m_gameWidth=320;
    private int m_gameHeight=350;
    private LivePlayer m_livePlayer;
    private Vec2 m_playerPos;
    private float m_playerAngle;
    private float m_zoom=1.0f;
    private float m_zoom2=0.5f;
   
    // TODO split into game thread and render thread 
    public JPlayThread(SurfaceHolder surfaceHolder,Context context){
        mSurfaceHolder=surfaceHolder;
        mContext = context;
        mRun=true;
        mClearPaint = new Paint();
        mClearPaint.setARGB(255,  120, 120, 120);
        mGameAreaPaint = new Paint();
        mGameAreaPaint.setARGB(255,  0,0 ,0);
        
        mScreenRect = new RectF(0,0,0,0);
    
        // init game
        m_renderObjects=new HashMap<String,AndroidRenderObject>();
        int gwidth=(int)(toWorld(m_gameWidth));
        int gheight=(int)(toWorld(m_gameHeight));
        m_game=new Game(gwidth*2,gheight*2);
        Game.game=m_game;
    
        // 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;//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);
    
            if(i==0){ 
                m_livePlayer=new LivePlayer(po);
                m_game.addPlayer(m_livePlayer,true);
            }else{
                m_game.addPlayer(new HunterPlayer(po,2));
            }
        }
    }


    /* Callback invoked when the surface dimensions change. */
    public void setSurfaceSize(int width, int height) {
        Log.v(TAG,"Surface size: "+width+"x"+height);
        // synchronized to make sure these all change atomically
        synchronized (mSurfaceHolder) {
            mScreenRect = new RectF(0,0,width,height);
        }
    }

    public void doKeys(int[] keys){
        // TODO update internal key map
    }
    
    @Override
    public void run() {
        int i=0;
        while(mRun){
            Canvas c = null;
            i++; 
    
            // tick then render
            //Log.v(TAG, "ticking");
            // TODO process key map for player actions
            synchronized(m_game){
                m_game.tick();
            }
   
            //Log.v("status","player object target: "+((PlayerObject)m_game.getPlayer()).getAngleTarget());
 
            try {
                c = mSurfaceHolder.lockCanvas(null);
                synchronized (mSurfaceHolder) {
                    //Log.v(TAG, "rendering");
                    doDraw(c);
                }
            } finally {
                // do this in a finally so that if an exception is thrown
                // during the above, we don't leave the Surface in an
                // inconsistent state
                if (c != null) {
                    mSurfaceHolder.unlockCanvasAndPost(c);
                }
            }
        }
    }
    
    private void doDraw(Canvas c){
        // TODO do dirty rect drawing
        c.drawRect(mScreenRect,mClearPaint);

        //retreive player position
        if(m_game.getPlayer().getBody()!=null){
            Body pb=m_game.getPlayer().getBody();
            m_playerPos=toScreen(pb.getPosition());
            m_playerAngle=pb.getAngle();
        }

        // Transform around player
        c.save();
        c.translate(m_gameWidth/2,m_gameHeight/2);
        // TODO make this zoom out on touch 
        if(m_zoom!=1.0){
            c.scale(m_zoom,m_zoom);
        } 
        c.rotate((float)Math.toDegrees(-m_playerAngle));
        c.translate(-m_playerPos.x,-m_playerPos.y);

        // TODO define game area
        c.drawRect(0,0,m_gameWidth*2,m_gameHeight*2,mGameAreaPaint);
    
        ArrayList<Renderable> renderables=m_game.getRenderables();
        //Log.v(TAG, "rendering "+renderables.size()+" objects");
    
        for(int i=0;i<renderables.size(); i++){
            Renderable r=renderables.get(i);
            AndroidRenderObject ro=(AndroidRenderObject)r.getRenderObject();
            if(ro==null){
                String k=r.getRenderKey();
                ro=m_renderObjects.get(k);
                if(ro==null){
                    Log.v(TAG," loading renderable "+k);
                    // TODO create render object
                    //ro=new PNGRenderObject("media/"+k+".png");
                    //Drawable img = context.getResources().getDrawable(R.drawable.lander_crashed);
                    // TODO find out how to use string lookups on Drawable resources
                    int h=R.drawable.bullet;
                    if(k=="tank2"){
                        h=R.drawable.tank2;
                    }
                    //ro=new DotRenderObject();
                    Drawable img = mContext.getResources().getDrawable(h);
                    ro=new DrawableRenderObject(img);
                    m_renderObjects.put(k,ro);
                }
            }
            float[] wt=r.getWorldTransform();
            ro.setCanvas(c);
            ro.setPixelRatio(PPM);
            ro.renderFromWorld(wt[0],wt[1],wt[2]);
        }
        c.restore();
    }
    
    public void setRunning(boolean b) {
        mRun = b;
    }

    /* 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 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(float n){
        return n/PPM;
    }

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

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

    private Vec2 toScreen(Vec2 v){
        return new Vec2(toScreen(v.x),toScreen(v.y));
    }
    
    public void triggerOn(){
        synchronized(m_game){
            m_game.getPlayer().triggerOn();
        }
    }

    public void triggerOff(){
        synchronized(m_game){
            m_game.getPlayer().triggerOff();
        }
    }

    // incoming as screen coords
    public void setPlayerAim(float x,float y){
        synchronized(m_game){
            PlayerObject po=(PlayerObject)m_game.getPlayer();
        }
    }
 
    public void setPlayerMoveTo(float x,float y){
        synchronized(m_game){
            PlayerObject po=(PlayerObject)m_game.getPlayer();
            po.rotateToPointAt(toWorld(x),toWorld(y));
        }
    }

    // use this to direct the player at the vec (x,y).. with accelerometer/orientation
    public void processPlayerDirection(float x,float y){
        synchronized(m_game){
            /*
            Vec2 i=new Vec2(x,y);
            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);
            */
            //float thresh=0.5f;
            if(x > 0.0f){
                m_game.getPlayer().right(x);
            }
            if(x < 0.0f){
                m_game.getPlayer().left(Math.abs(x));
            }

            m_game.getPlayer().setThrottle(-y);
    
        } 
    }
    
    public void zoomOut(){
        m_zoom=0.5f;
    }

    public void zoomIn(){
        m_zoom=1.0f;
    }
}




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