If you think the Android project clash_of_balls 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
/*
* Copyright (C) 2012-2013 Hans Hardmeier <hanshardmeier@gmail.com>
* Copyright (C) 2012-2013 Andrin Jenal//fromwww.java2s.com
* Copyright (C) 2012-2013 Beat Kng <beat-kueng@gmx.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/package com.sapos_aplastados.game.clash_of_balls.game;
import org.jbox2d.common.Vec2;
import com.sapos_aplastados.game.clash_of_balls.GameSettings;
import com.sapos_aplastados.game.clash_of_balls.Texture;
/**
* all game objects that can be dynamically added or removed must inherit from
* this class
*
* move() must not change m_position, but m_new_pos instead
* this is then used in the game for object collision detection
*
*/publicclass DynamicGameObject extends StaticGameObject {
/* death of an object:
* m_bIs_dead==true: means that this object cannot interact with others anymore
* m_bIs_dying==true: implies m_bIs_dead==true. means the object is still in the
* object list, but cannot move anymore. used for dying effect
* m_bIs_dead && !m_bIs_dying: means the object is not used anymore
*/protectedboolean m_bIs_dead = false;
publicboolean isDead() { return m_bIs_dead; }
protectedboolean m_bIs_dying = false;
publicboolean isReallyDead() { return m_bIs_dead && !m_bIs_dying; }
privateint m_impact_count = 0;
protected GameBase m_owner;
DynamicGameObject(GameBase owner, finalshort id, Type type
, Texture texture) {
super(id, type, texture);
m_owner = owner;
}
//can be used for shadow drawing etc...
publicvoid drawBackground(RenderHelper renderer) {
}
@Override
publicvoid draw(RenderHelper renderer) {
if(!isReallyDead()) {
super.draw(renderer);
}
}
private Vector m_server_translation = new Vector(0.f, 0.f);
privatestaticfinalfloat SERVER_POS_SMOOTHING = 1.f/5.f;
//this defines how smoothly the server position update
//is applied. a bigger value means less smoothly but
//more accruate with the server (1 means apply in one step)
//it takes ln(0.01)/ln(1-SERVER_POS_SMOOTHING) frames (steps)
//to get the error (distance of positions) below 0.01
//for SERVER_POS_SMOOTHING = 1/5 it's about 20 frames
private Vec2 m_tmp_vec = new Vec2();
publicvoid applyVectorData(Vector new_pos, Vector new_speed) {
m_tmp_vec.set(new_speed.x, new_speed.y);
m_body.setLinearVelocity(m_tmp_vec);
if(GameSettings.client_prediction) {
//apply position smoothly
//we cannot simply change m_position or m_new_pos because we would need
//to do collision handling
m_server_translation.set(new_pos.x - m_body.getPosition().x
, new_pos.y - m_body.getPosition().y);
} else {
m_tmp_vec.set(new_pos.x, new_pos.y);
m_body.setTransform(m_tmp_vec, m_body.getAngle());
}
}
//handle everything in here updated by the server. like position & speed
//all these operations must be undoable or overwritable by a server update!
@Override
publicvoid move(float dsec) {
//check for client-side smoothing of server position update
if(Math.abs(m_server_translation.x) > GameBase.EPS
|| Math.abs(m_server_translation.y) > GameBase.EPS) {
if(m_server_translation.length() < 0.02f) {
m_tmp_vec.set(m_body.getPosition().x + m_server_translation.x
, m_body.getPosition().y + m_server_translation.y);
m_body.setTransform(m_tmp_vec, m_body.getAngle());
m_server_translation.set(0.f, 0.f);
} else {
float dx = m_server_translation.x * SERVER_POS_SMOOTHING;
float dy = m_server_translation.y * SERVER_POS_SMOOTHING;
m_tmp_vec.set(m_body.getPosition().x + dx
, m_body.getPosition().y + dy);
m_body.setTransform(m_tmp_vec, m_body.getAngle());
m_server_translation.sub(dx, dy);
}
}
}
//every change that does not need to be updated by the server can be handled
//in here
//this can also be called by the server & is used to move less important
//stuff like animation or item timeout's
//do NOT generate Events in here
publicvoid moveClient(float dsec) {
}
publicvoid handleImpact(StaticGameObject other, Vector normal) {
++m_impact_count;
}
publicint impactCount() { return m_impact_count; }
publicvoid die() {
if(!m_bIs_dead) {
m_bIs_dead = true;
m_bIs_dying = false;
m_owner.handleObjectDied(this);
}
}
}